Fix PIPELINE_STAGE_TOP_OF_PIPE_BIT usage in api tests
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fVertexAttributeBindingStateQueryTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 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 Vertex attribute binding state query tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fVertexAttributeBindingStateQueryTests.hpp"
25 #include "tcuTestLog.hpp"
26 #include "gluCallLogWrapper.hpp"
27 #include "gluRenderContext.hpp"
28 #include "gluObjectWrapper.hpp"
29 #include "gluStrUtil.hpp"
30 #include "glsStateQueryUtil.hpp"
31 #include "glwEnums.hpp"
32 #include "glwFunctions.hpp"
33 #include "glsStateQueryUtil.hpp"
34 #include "deRandom.hpp"
35
36 namespace deqp
37 {
38 namespace gles31
39 {
40 namespace Functional
41 {
42 namespace
43 {
44
45 using namespace gls::StateQueryUtil;
46
47 class AttributeCase : public TestCase
48 {
49 public:
50                                                 AttributeCase           (Context& context, const char* name, const char* desc, QueryType verifier);
51
52         IterateResult           iterate                         (void);
53         virtual void            test                            (tcu::ResultCollector& result) = 0;
54
55 protected:
56         const QueryType         m_verifier;
57 };
58
59 AttributeCase::AttributeCase (Context& context, const char* name, const char* desc, QueryType verifier)
60         : TestCase              (context, name, desc)
61         , m_verifier    (verifier)
62 {
63 }
64
65 AttributeCase::IterateResult AttributeCase::iterate (void)
66 {
67         tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
68
69         test(result);
70
71         result.setTestContextResult(m_testCtx);
72         return STOP;
73 }
74
75 class AttributeBindingCase : public AttributeCase
76 {
77 public:
78                         AttributeBindingCase    (Context& context, const char* name, const char* desc, QueryType verifier);
79         void    test                                    (tcu::ResultCollector& result);
80 };
81
82 AttributeBindingCase::AttributeBindingCase (Context& context, const char* name, const char* desc, QueryType verifier)
83         : AttributeCase(context, name, desc, verifier)
84 {
85 }
86
87 void AttributeBindingCase::test (tcu::ResultCollector& result)
88 {
89         glu::CallLogWrapper gl                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
90         glu::VertexArray        vao                     (m_context.getRenderContext());
91         glw::GLint                      maxAttrs        = -1;
92
93         gl.enableLogging(true);
94
95         gl.glBindVertexArray(*vao);
96         gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs);
97         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
98
99         // initial
100         {
101                 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
102
103                 for (int attr = 0; attr < de::max(16, maxAttrs); ++attr)
104                         verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_BINDING, attr, attr, m_verifier);
105         }
106
107         // is part of vao
108         {
109                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "vao", "VAO state");
110                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
111
112                 // set to value A in vao1
113                 gl.glVertexAttribBinding(1, 4);
114                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribBinding");
115
116                 // set to value B in vao2
117                 gl.glBindVertexArray(*otherVao);
118                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
119
120                 gl.glVertexAttribBinding(1, 7);
121                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribBinding");
122
123                 // check value is still ok in original vao
124                 gl.glBindVertexArray(*vao);
125                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
126
127                 verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_BINDING, 1, 4, m_verifier);
128         }
129
130         // random values
131         {
132                 const tcu::ScopedLogSection     section                 (m_testCtx.getLog(), "random", "Random values");
133                 de::Random                                      rnd                             (0xabc);
134                 const int                                       numRandomTests  = 10;
135
136                 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
137                 {
138                         // switch random va to random binding
139                         const int       va                              = rnd.getInt(0, de::max(16, maxAttrs)-1);
140                         const int       binding                 = rnd.getInt(0, 16);
141
142                         gl.glVertexAttribBinding(va, binding);
143                         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribBinding");
144
145                         verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_BINDING, va, binding, m_verifier);
146                 }
147         }
148 }
149
150 class AttributeRelativeOffsetCase : public AttributeCase
151 {
152 public:
153                         AttributeRelativeOffsetCase     (Context& context, const char* name, const char* desc, QueryType verifier);
154         void    test                                            (tcu::ResultCollector& result);
155 };
156
157 AttributeRelativeOffsetCase::AttributeRelativeOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier)
158         : AttributeCase(context, name, desc, verifier)
159 {
160 }
161
162 void AttributeRelativeOffsetCase::test (tcu::ResultCollector& result)
163 {
164         glu::CallLogWrapper gl                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
165         glu::VertexArray        vao                     (m_context.getRenderContext());
166         glw::GLint                      maxAttrs        = -1;
167
168         gl.enableLogging(true);
169
170         gl.glBindVertexArray(*vao);
171         gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs);
172         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
173
174         // initial
175         {
176                 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
177
178                 for (int attr = 0; attr < de::max(16, maxAttrs); ++attr)
179                         verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, attr, 0, m_verifier);
180         }
181
182         // is part of vao
183         {
184                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "vao", "VAO state");
185                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
186
187                 // set to value A in vao1
188                 gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 9);
189                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
190
191                 // set to value B in vao2
192                 gl.glBindVertexArray(*otherVao);
193                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
194
195                 gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 21);
196                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
197
198                 // check value is still ok in original vao
199                 gl.glBindVertexArray(*vao);
200                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
201
202                 verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 9, m_verifier);
203         }
204
205         // random values
206         {
207                 const tcu::ScopedLogSection     section                 (m_testCtx.getLog(), "random", "Random values");
208                 de::Random                                      rnd                             (0xabc);
209                 const int                                       numRandomTests  = 10;
210
211                 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
212                 {
213                         const int       va                              = rnd.getInt(0, de::max(16, maxAttrs)-1);
214                         const int       offset                  = rnd.getInt(0, 2047);
215
216                         gl.glVertexAttribFormat(va, 4, GL_FLOAT, GL_FALSE, offset);
217                         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
218
219                         verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, va, offset, m_verifier);
220                 }
221         }
222 }
223
224 class IndexedCase : public TestCase
225 {
226 public:
227                                                 IndexedCase                     (Context& context, const char* name, const char* desc, QueryType verifier);
228
229         IterateResult           iterate                         (void);
230         virtual void            test                            (tcu::ResultCollector& result) = 0;
231
232 protected:
233         const QueryType         m_verifier;
234 };
235
236 IndexedCase::IndexedCase (Context& context, const char* name, const char* desc, QueryType verifier)
237         : TestCase              (context, name, desc)
238         , m_verifier    (verifier)
239 {
240 }
241
242 IndexedCase::IterateResult IndexedCase::iterate (void)
243 {
244         tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
245
246         test(result);
247
248         result.setTestContextResult(m_testCtx);
249         return STOP;
250 }
251
252 class VertexBindingDivisorCase : public IndexedCase
253 {
254 public:
255                         VertexBindingDivisorCase        (Context& context, const char* name, const char* desc, QueryType verifier);
256         void    test                                            (tcu::ResultCollector& result);
257 };
258
259 VertexBindingDivisorCase::VertexBindingDivisorCase (Context& context, const char* name, const char* desc, QueryType verifier)
260         : IndexedCase(context, name, desc, verifier)
261 {
262 }
263
264 void VertexBindingDivisorCase::test (tcu::ResultCollector& result)
265 {
266         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
267         glu::VertexArray        vao                                     (m_context.getRenderContext());
268         glw::GLint                      reportedMaxBindings     = -1;
269         glw::GLint                      maxBindings;
270
271         gl.enableLogging(true);
272
273         gl.glBindVertexArray(*vao);
274         gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
275         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
276
277         maxBindings = de::max(16, reportedMaxBindings);
278
279         // initial
280         {
281                 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
282
283                 for (int binding = 0; binding < maxBindings; ++binding)
284                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, binding, 0, m_verifier);
285         }
286
287         // is part of vao
288         {
289                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "vao", "VAO state");
290                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
291
292                 // set to value A in vao1
293                 gl.glVertexBindingDivisor(1, 4);
294                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
295
296                 // set to value B in vao2
297                 gl.glBindVertexArray(*otherVao);
298                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
299
300                 gl.glVertexBindingDivisor(1, 9);
301                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
302
303                 // check value is still ok in original vao
304                 gl.glBindVertexArray(*vao);
305                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
306
307                 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, 1, 4, m_verifier);
308         }
309
310         // random values
311         {
312                 const tcu::ScopedLogSection     section                 (m_testCtx.getLog(), "random", "Random values");
313                 de::Random                                      rnd                             (0xabc);
314                 const int                                       numRandomTests  = 10;
315
316                 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
317                 {
318                         const int       binding                 = rnd.getInt(0, maxBindings-1);
319                         const int       divisor                 = rnd.getInt(0, 2047);
320
321                         gl.glVertexBindingDivisor(binding, divisor);
322                         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
323
324                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, binding, divisor, m_verifier);
325                 }
326         }
327 }
328
329 class VertexBindingOffsetCase : public IndexedCase
330 {
331 public:
332                         VertexBindingOffsetCase         (Context& context, const char* name, const char* desc, QueryType verifier);
333         void    test                                            (tcu::ResultCollector& result);
334 };
335
336 VertexBindingOffsetCase::VertexBindingOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier)
337         : IndexedCase(context, name, desc, verifier)
338 {
339 }
340
341 void VertexBindingOffsetCase::test (tcu::ResultCollector& result)
342 {
343         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
344         glu::VertexArray        vao                                     (m_context.getRenderContext());
345         glu::Buffer                     buffer                          (m_context.getRenderContext());
346         glw::GLint                      reportedMaxBindings     = -1;
347         glw::GLint                      maxBindings;
348
349         gl.enableLogging(true);
350
351         gl.glBindVertexArray(*vao);
352         gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
353         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
354
355         maxBindings = de::max(16, reportedMaxBindings);
356
357         // initial
358         {
359                 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
360
361                 for (int binding = 0; binding < maxBindings; ++binding)
362                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, binding, 0, m_verifier);
363         }
364
365         // is part of vao
366         {
367                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "vao", "VAO state");
368                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
369
370                 // set to value A in vao1
371                 gl.glBindVertexBuffer(1, *buffer, 4, 32);
372                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
373
374                 // set to value B in vao2
375                 gl.glBindVertexArray(*otherVao);
376                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
377
378                 gl.glBindVertexBuffer(1, *buffer, 13, 32);
379                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
380
381                 // check value is still ok in original vao
382                 gl.glBindVertexArray(*vao);
383                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
384
385                 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, 1, 4, m_verifier);
386         }
387
388         // random values
389         {
390                 const tcu::ScopedLogSection     section                 (m_testCtx.getLog(), "random", "Random values");
391                 de::Random                                      rnd                             (0xabc);
392                 const int                                       numRandomTests  = 10;
393
394                 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
395                 {
396                         const int       binding                 = rnd.getInt(0, maxBindings-1);
397                         const int       offset                  = rnd.getInt(0, 4000);
398
399                         gl.glBindVertexBuffer(binding, *buffer, offset, 32);
400                         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
401
402                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, binding, offset, m_verifier);
403                 }
404         }
405 }
406
407 class VertexBindingStrideCase : public IndexedCase
408 {
409 public:
410                         VertexBindingStrideCase         (Context& context, const char* name, const char* desc, QueryType verifier);
411         void    test                                            (tcu::ResultCollector& result);
412 };
413
414 VertexBindingStrideCase::VertexBindingStrideCase (Context& context, const char* name, const char* desc, QueryType verifier)
415         : IndexedCase(context, name, desc, verifier)
416 {
417 }
418
419 void VertexBindingStrideCase::test (tcu::ResultCollector& result)
420 {
421         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
422         glu::VertexArray        vao                                     (m_context.getRenderContext());
423         glu::Buffer                     buffer                          (m_context.getRenderContext());
424         glw::GLint                      reportedMaxBindings     = -1;
425         glw::GLint                      maxBindings;
426
427         gl.enableLogging(true);
428
429         gl.glBindVertexArray(*vao);
430         gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
431         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
432
433         maxBindings = de::max(16, reportedMaxBindings);
434
435         // initial
436         {
437                 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
438
439                 for (int binding = 0; binding < maxBindings; ++binding)
440                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, binding, 16, m_verifier);
441         }
442
443         // is part of vao
444         {
445                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "vao", "VAO state");
446                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
447
448                 // set to value A in vao1
449                 gl.glBindVertexBuffer(1, *buffer, 0, 32);
450                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
451
452                 // set to value B in vao2
453                 gl.glBindVertexArray(*otherVao);
454                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
455
456                 gl.glBindVertexBuffer(1, *buffer, 0, 64);
457                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
458
459                 // check value is still ok in original vao
460                 gl.glBindVertexArray(*vao);
461                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
462
463                 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 32, m_verifier);
464         }
465
466         // random values
467         {
468                 const tcu::ScopedLogSection     section                 (m_testCtx.getLog(), "random", "Random values");
469                 de::Random                                      rnd                             (0xabc);
470                 const int                                       numRandomTests  = 10;
471
472                 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
473                 {
474                         const int       binding                 = rnd.getInt(0, maxBindings-1);
475                         const int       stride                  = rnd.getInt(0, 2048);
476
477                         gl.glBindVertexBuffer(binding, *buffer, 0, stride);
478                         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
479
480                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, binding, stride, m_verifier);
481                 }
482         }
483 }
484
485 class VertexBindingBufferCase : public IndexedCase
486 {
487 public:
488                         VertexBindingBufferCase         (Context& context, const char* name, const char* desc, QueryType verifier);
489         void    test                                            (tcu::ResultCollector& result);
490 };
491
492 VertexBindingBufferCase::VertexBindingBufferCase (Context& context, const char* name, const char* desc, QueryType verifier)
493         : IndexedCase(context, name, desc, verifier)
494 {
495 }
496
497 void VertexBindingBufferCase::test (tcu::ResultCollector& result)
498 {
499         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
500         glu::VertexArray        vao                                     (m_context.getRenderContext());
501         glu::Buffer                     buffer                          (m_context.getRenderContext());
502         glw::GLint                      reportedMaxBindings     = -1;
503         glw::GLint                      maxBindings;
504
505         gl.enableLogging(true);
506
507         gl.glBindVertexArray(*vao);
508         gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
509         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
510
511         maxBindings = de::max(16, reportedMaxBindings);
512
513         // initial
514         {
515                 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
516
517                 for (int binding = 0; binding < maxBindings; ++binding)
518                         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, binding, 0, m_verifier);
519         }
520
521         // is part of vao
522         {
523                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "vao", "VAO state");
524                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
525                 glu::Buffer                                     otherBuffer             (m_context.getRenderContext());
526
527                 // set to value A in vao1
528                 gl.glBindVertexBuffer(1, *buffer, 0, 32);
529                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
530
531                 // set to value B in vao2
532                 gl.glBindVertexArray(*otherVao);
533                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
534                 gl.glBindVertexBuffer(1, *otherBuffer, 0, 32);
535                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
536
537                 // check value is still ok in original vao
538                 gl.glBindVertexArray(*vao);
539                 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
540
541                 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer, m_verifier);
542         }
543
544         // Is detached in delete from active vao and not from deactive
545         {
546                 const tcu::ScopedLogSection section                     (m_testCtx.getLog(), "autoUnbind", "Unbind on delete");
547                 glu::VertexArray                        otherVao                (m_context.getRenderContext());
548                 glw::GLuint                                     otherBuffer             = -1;
549
550                 gl.glGenBuffers(1, &otherBuffer);
551
552                 // set in vao1 and vao2
553                 gl.glBindVertexBuffer(1, otherBuffer, 0, 32);
554                 gl.glBindVertexArray(*otherVao);
555                 gl.glBindVertexBuffer(1, otherBuffer, 0, 32);
556
557                 // delete buffer. This unbinds it from active (vao2) but not from unactive
558                 gl.glDeleteBuffers(1, &otherBuffer);
559                 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, 0, m_verifier);
560
561                 gl.glBindVertexArray(*vao);
562                 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, otherBuffer, m_verifier);
563         }
564 }
565
566 class MixedVertexBindingDivisorCase : public IndexedCase
567 {
568 public:
569                         MixedVertexBindingDivisorCase   (Context& context, const char* name, const char* desc);
570         void    test                                                    (tcu::ResultCollector& result);
571 };
572
573 MixedVertexBindingDivisorCase::MixedVertexBindingDivisorCase (Context& context, const char* name, const char* desc)
574         : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
575 {
576 }
577
578 void MixedVertexBindingDivisorCase::test (tcu::ResultCollector& result)
579 {
580         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
581         glu::VertexArray        vao                                     (m_context.getRenderContext());
582
583         gl.enableLogging(true);
584
585         gl.glBindVertexArray(*vao);
586         gl.glVertexAttribDivisor(1, 4);
587         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, 1, 4, m_verifier);
588 }
589
590 class MixedVertexBindingOffsetCase : public IndexedCase
591 {
592 public:
593                         MixedVertexBindingOffsetCase    (Context& context, const char* name, const char* desc);
594         void    test                                                    (tcu::ResultCollector& result);
595 };
596
597 MixedVertexBindingOffsetCase::MixedVertexBindingOffsetCase (Context& context, const char* name, const char* desc)
598         : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
599 {
600 }
601
602 void MixedVertexBindingOffsetCase::test (tcu::ResultCollector& result)
603 {
604         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
605         glu::Buffer                     buffer                          (m_context.getRenderContext());
606
607         gl.enableLogging(true);
608
609         gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
610         gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const deUint8*)DE_NULL + 12);
611
612         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, 1, 12, m_verifier);
613 }
614
615 class MixedVertexBindingStrideCase : public IndexedCase
616 {
617 public:
618                         MixedVertexBindingStrideCase    (Context& context, const char* name, const char* desc);
619         void    test                                                    (tcu::ResultCollector& result);
620 };
621
622 MixedVertexBindingStrideCase::MixedVertexBindingStrideCase (Context& context, const char* name, const char* desc)
623         : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
624 {
625 }
626
627 void MixedVertexBindingStrideCase::test (tcu::ResultCollector& result)
628 {
629         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
630         glu::Buffer                     buffer                          (m_context.getRenderContext());
631
632         gl.enableLogging(true);
633
634         gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
635         gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 12, 0);
636         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 12, m_verifier);
637
638         // test effectiveStride
639         gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
640         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 16, m_verifier);
641 }
642
643 class MixedVertexBindingBufferCase : public IndexedCase
644 {
645 public:
646                         MixedVertexBindingBufferCase    (Context& context, const char* name, const char* desc);
647         void    test                                                    (tcu::ResultCollector& result);
648 };
649
650 MixedVertexBindingBufferCase::MixedVertexBindingBufferCase (Context& context, const char* name, const char* desc)
651         : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
652 {
653 }
654
655 void MixedVertexBindingBufferCase::test (tcu::ResultCollector& result)
656 {
657         glu::CallLogWrapper gl                                  (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
658         glu::Buffer                     buffer                          (m_context.getRenderContext());
659
660         gl.enableLogging(true);
661
662         gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
663         gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
664         verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer, m_verifier);
665 }
666
667 } // anonymous
668
669 VertexAttributeBindingStateQueryTests::VertexAttributeBindingStateQueryTests (Context& context)
670         : TestCaseGroup(context, "vertex_attribute_binding", "Query vertex attribute binding state.")
671 {
672 }
673
674 VertexAttributeBindingStateQueryTests::~VertexAttributeBindingStateQueryTests (void)
675 {
676 }
677
678 void VertexAttributeBindingStateQueryTests::init (void)
679 {
680         tcu::TestCaseGroup* const attributeGroup        = new TestCaseGroup(m_context, "vertex_attrib", "Vertex attribute state");
681         tcu::TestCaseGroup* const indexedGroup          = new TestCaseGroup(m_context, "indexed", "Indexed state");
682
683         addChild(attributeGroup);
684         addChild(indexedGroup);
685
686         // .vertex_attrib
687         {
688                 static const struct Verifier
689                 {
690                         const char*             suffix;
691                         QueryType               type;
692                 } verifiers[] =
693                 {
694                         { "",                                           QUERY_ATTRIBUTE_INTEGER                                 },      // avoid renaming tests
695                         { "_getvertexattribfv",         QUERY_ATTRIBUTE_FLOAT                                   },
696                         { "_getvertexattribiiv",        QUERY_ATTRIBUTE_PURE_INTEGER                    },
697                         { "_getvertexattribiuiv",       QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER   },
698                 };
699
700                 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
701                 {
702                         attributeGroup->addChild(new AttributeBindingCase               (m_context,     (std::string("vertex_attrib_binding") + verifiers[verifierNdx].suffix).c_str(),                 "Test VERTEX_ATTRIB_BINDING",                   verifiers[verifierNdx].type));
703                         attributeGroup->addChild(new AttributeRelativeOffsetCase(m_context,     (std::string("vertex_attrib_relative_offset") + verifiers[verifierNdx].suffix).c_str(), "Test VERTEX_ATTRIB_RELATIVE_OFFSET",   verifiers[verifierNdx].type));
704                 }
705         }
706
707         // .indexed
708         {
709                 static const struct Verifier
710                 {
711                         const char*             name;
712                         QueryType               type;
713                 } verifiers[] =
714                 {
715                         { "getintegeri",        QUERY_INDEXED_INTEGER   },
716                         { "getintegeri64",      QUERY_INDEXED_INTEGER64 },
717                         { "getboolean",         QUERY_INDEXED_BOOLEAN   },
718                 };
719
720                 // states
721
722                 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
723                 {
724                         indexedGroup->addChild(new VertexBindingDivisorCase     (m_context, (std::string("vertex_binding_divisor_") + verifiers[verifierNdx].name).c_str(),     "Test VERTEX_BINDING_DIVISOR",  verifiers[verifierNdx].type));
725                         indexedGroup->addChild(new VertexBindingOffsetCase      (m_context, (std::string("vertex_binding_offset_") + verifiers[verifierNdx].name).c_str(),      "Test VERTEX_BINDING_OFFSET",   verifiers[verifierNdx].type));
726                         indexedGroup->addChild(new VertexBindingStrideCase      (m_context, (std::string("vertex_binding_stride_") + verifiers[verifierNdx].name).c_str(),      "Test VERTEX_BINDING_STRIDE",   verifiers[verifierNdx].type));
727                         indexedGroup->addChild(new VertexBindingBufferCase      (m_context, (std::string("vertex_binding_buffer_") + verifiers[verifierNdx].name).c_str(),      "Test VERTEX_BINDING_BUFFER",   verifiers[verifierNdx].type));
728                 }
729
730                 // mixed apis
731
732                 indexedGroup->addChild(new MixedVertexBindingDivisorCase(m_context, "vertex_binding_divisor_mixed",     "Test VERTEX_BINDING_DIVISOR"));
733                 indexedGroup->addChild(new MixedVertexBindingOffsetCase (m_context, "vertex_binding_offset_mixed",      "Test VERTEX_BINDING_OFFSET"));
734                 indexedGroup->addChild(new MixedVertexBindingStrideCase (m_context, "vertex_binding_stride_mixed",      "Test VERTEX_BINDING_STRIDE"));
735                 indexedGroup->addChild(new MixedVertexBindingBufferCase (m_context, "vertex_binding_buffer_mixed",      "Test VERTEX_BINDING_BUFFER"));
736         }
737 }
738
739 } // Functional
740 } // gles31
741 } // deqp