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
AttributeCase(Context & context,const char * name,const char * desc,QueryType verifier)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
iterate(void)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
AttributeBindingCase(Context & context,const char * name,const char * desc,QueryType verifier)82 AttributeBindingCase::AttributeBindingCase(Context &context, const char *name, const char *desc, QueryType verifier)
83 : AttributeCase(context, name, desc, verifier)
84 {
85 }
86
test(tcu::ResultCollector & result)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
AttributeRelativeOffsetCase(Context & context,const char * name,const char * desc,QueryType verifier)157 AttributeRelativeOffsetCase::AttributeRelativeOffsetCase(Context &context, const char *name, const char *desc,
158 QueryType verifier)
159 : AttributeCase(context, name, desc, verifier)
160 {
161 }
162
test(tcu::ResultCollector & result)163 void AttributeRelativeOffsetCase::test(tcu::ResultCollector &result)
164 {
165 glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
166 glu::VertexArray vao(m_context.getRenderContext());
167 glw::GLint maxAttrs = -1;
168
169 gl.enableLogging(true);
170
171 gl.glBindVertexArray(*vao);
172 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrs);
173 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
174
175 // initial
176 {
177 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
178
179 for (int attr = 0; attr < de::max(16, maxAttrs); ++attr)
180 verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, attr, 0, m_verifier);
181 }
182
183 // is part of vao
184 {
185 const tcu::ScopedLogSection section(m_testCtx.getLog(), "vao", "VAO state");
186 glu::VertexArray otherVao(m_context.getRenderContext());
187
188 // set to value A in vao1
189 gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 9);
190 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
191
192 // set to value B in vao2
193 gl.glBindVertexArray(*otherVao);
194 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
195
196 gl.glVertexAttribFormat(1, 4, GL_FLOAT, GL_FALSE, 21);
197 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
198
199 // check value is still ok in original vao
200 gl.glBindVertexArray(*vao);
201 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
202
203 verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 9, m_verifier);
204 }
205
206 // random values
207 {
208 const tcu::ScopedLogSection section(m_testCtx.getLog(), "random", "Random values");
209 de::Random rnd(0xabc);
210 const int numRandomTests = 10;
211
212 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
213 {
214 const int va = rnd.getInt(0, de::max(16, maxAttrs) - 1);
215 const int offset = rnd.getInt(0, 2047);
216
217 gl.glVertexAttribFormat(va, 4, GL_FLOAT, GL_FALSE, offset);
218 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexAttribFormat");
219
220 verifyStateAttributeInteger(result, gl, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, va, offset, m_verifier);
221 }
222 }
223 }
224
225 class IndexedCase : public TestCase
226 {
227 public:
228 IndexedCase(Context &context, const char *name, const char *desc, QueryType verifier);
229
230 IterateResult iterate(void);
231 virtual void test(tcu::ResultCollector &result) = 0;
232
233 protected:
234 const QueryType m_verifier;
235 };
236
IndexedCase(Context & context,const char * name,const char * desc,QueryType verifier)237 IndexedCase::IndexedCase(Context &context, const char *name, const char *desc, QueryType verifier)
238 : TestCase(context, name, desc)
239 , m_verifier(verifier)
240 {
241 }
242
iterate(void)243 IndexedCase::IterateResult IndexedCase::iterate(void)
244 {
245 tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
246
247 test(result);
248
249 result.setTestContextResult(m_testCtx);
250 return STOP;
251 }
252
253 class VertexBindingDivisorCase : public IndexedCase
254 {
255 public:
256 VertexBindingDivisorCase(Context &context, const char *name, const char *desc, QueryType verifier);
257 void test(tcu::ResultCollector &result);
258 };
259
VertexBindingDivisorCase(Context & context,const char * name,const char * desc,QueryType verifier)260 VertexBindingDivisorCase::VertexBindingDivisorCase(Context &context, const char *name, const char *desc,
261 QueryType verifier)
262 : IndexedCase(context, name, desc, verifier)
263 {
264 }
265
test(tcu::ResultCollector & result)266 void VertexBindingDivisorCase::test(tcu::ResultCollector &result)
267 {
268 glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
269 glu::VertexArray vao(m_context.getRenderContext());
270 glw::GLint reportedMaxBindings = -1;
271 glw::GLint maxBindings;
272
273 gl.enableLogging(true);
274
275 gl.glBindVertexArray(*vao);
276 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
277 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
278
279 maxBindings = de::max(16, reportedMaxBindings);
280
281 // initial
282 {
283 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
284
285 for (int binding = 0; binding < maxBindings; ++binding)
286 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, binding, 0, m_verifier);
287 }
288
289 // is part of vao
290 {
291 const tcu::ScopedLogSection section(m_testCtx.getLog(), "vao", "VAO state");
292 glu::VertexArray otherVao(m_context.getRenderContext());
293
294 // set to value A in vao1
295 gl.glVertexBindingDivisor(1, 4);
296 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
297
298 // set to value B in vao2
299 gl.glBindVertexArray(*otherVao);
300 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
301
302 gl.glVertexBindingDivisor(1, 9);
303 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
304
305 // check value is still ok in original vao
306 gl.glBindVertexArray(*vao);
307 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
308
309 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, 1, 4, m_verifier);
310 }
311
312 // random values
313 {
314 const tcu::ScopedLogSection section(m_testCtx.getLog(), "random", "Random values");
315 de::Random rnd(0xabc);
316 const int numRandomTests = 10;
317
318 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
319 {
320 const int binding = rnd.getInt(0, maxBindings - 1);
321 const int divisor = rnd.getInt(0, 2047);
322
323 gl.glVertexBindingDivisor(binding, divisor);
324 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glVertexBindingDivisor");
325
326 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, binding, divisor, m_verifier);
327 }
328 }
329 }
330
331 class VertexBindingOffsetCase : public IndexedCase
332 {
333 public:
334 VertexBindingOffsetCase(Context &context, const char *name, const char *desc, QueryType verifier);
335 void test(tcu::ResultCollector &result);
336 };
337
VertexBindingOffsetCase(Context & context,const char * name,const char * desc,QueryType verifier)338 VertexBindingOffsetCase::VertexBindingOffsetCase(Context &context, const char *name, const char *desc,
339 QueryType verifier)
340 : IndexedCase(context, name, desc, verifier)
341 {
342 }
343
test(tcu::ResultCollector & result)344 void VertexBindingOffsetCase::test(tcu::ResultCollector &result)
345 {
346 glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
347 glu::VertexArray vao(m_context.getRenderContext());
348 glu::Buffer buffer(m_context.getRenderContext());
349 glw::GLint reportedMaxBindings = -1;
350 glw::GLint maxBindings;
351
352 gl.enableLogging(true);
353
354 gl.glBindVertexArray(*vao);
355 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
356 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
357
358 maxBindings = de::max(16, reportedMaxBindings);
359
360 // initial
361 {
362 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
363
364 for (int binding = 0; binding < maxBindings; ++binding)
365 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, binding, 0, m_verifier);
366 }
367
368 // is part of vao
369 {
370 const tcu::ScopedLogSection section(m_testCtx.getLog(), "vao", "VAO state");
371 glu::VertexArray otherVao(m_context.getRenderContext());
372
373 // set to value A in vao1
374 gl.glBindVertexBuffer(1, *buffer, 4, 32);
375 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
376
377 // set to value B in vao2
378 gl.glBindVertexArray(*otherVao);
379 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
380
381 gl.glBindVertexBuffer(1, *buffer, 13, 32);
382 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
383
384 // check value is still ok in original vao
385 gl.glBindVertexArray(*vao);
386 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
387
388 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, 1, 4, m_verifier);
389 }
390
391 // random values
392 {
393 const tcu::ScopedLogSection section(m_testCtx.getLog(), "random", "Random values");
394 de::Random rnd(0xabc);
395 const int numRandomTests = 10;
396
397 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
398 {
399 const int binding = rnd.getInt(0, maxBindings - 1);
400 const int offset = rnd.getInt(0, 4000);
401
402 gl.glBindVertexBuffer(binding, *buffer, offset, 32);
403 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
404
405 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, binding, offset, m_verifier);
406 }
407 }
408 }
409
410 class VertexBindingStrideCase : public IndexedCase
411 {
412 public:
413 VertexBindingStrideCase(Context &context, const char *name, const char *desc, QueryType verifier);
414 void test(tcu::ResultCollector &result);
415 };
416
VertexBindingStrideCase(Context & context,const char * name,const char * desc,QueryType verifier)417 VertexBindingStrideCase::VertexBindingStrideCase(Context &context, const char *name, const char *desc,
418 QueryType verifier)
419 : IndexedCase(context, name, desc, verifier)
420 {
421 }
422
test(tcu::ResultCollector & result)423 void VertexBindingStrideCase::test(tcu::ResultCollector &result)
424 {
425 glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
426 glu::VertexArray vao(m_context.getRenderContext());
427 glu::Buffer buffer(m_context.getRenderContext());
428 glw::GLint reportedMaxBindings = -1;
429 glw::GLint maxBindings;
430
431 gl.enableLogging(true);
432
433 gl.glBindVertexArray(*vao);
434 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
435 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
436
437 maxBindings = de::max(16, reportedMaxBindings);
438
439 // initial
440 {
441 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
442
443 for (int binding = 0; binding < maxBindings; ++binding)
444 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, binding, 16, m_verifier);
445 }
446
447 // is part of vao
448 {
449 const tcu::ScopedLogSection section(m_testCtx.getLog(), "vao", "VAO state");
450 glu::VertexArray otherVao(m_context.getRenderContext());
451
452 // set to value A in vao1
453 gl.glBindVertexBuffer(1, *buffer, 0, 32);
454 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
455
456 // set to value B in vao2
457 gl.glBindVertexArray(*otherVao);
458 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
459
460 gl.glBindVertexBuffer(1, *buffer, 0, 64);
461 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
462
463 // check value is still ok in original vao
464 gl.glBindVertexArray(*vao);
465 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
466
467 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 32, m_verifier);
468 }
469
470 // random values
471 {
472 const tcu::ScopedLogSection section(m_testCtx.getLog(), "random", "Random values");
473 de::Random rnd(0xabc);
474 const int numRandomTests = 10;
475
476 for (int randomTestNdx = 0; randomTestNdx < numRandomTests; ++randomTestNdx)
477 {
478 const int binding = rnd.getInt(0, maxBindings - 1);
479 const int stride = rnd.getInt(0, 2048);
480
481 gl.glBindVertexBuffer(binding, *buffer, 0, stride);
482 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
483
484 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, binding, stride, m_verifier);
485 }
486 }
487 }
488
489 class VertexBindingBufferCase : public IndexedCase
490 {
491 public:
492 VertexBindingBufferCase(Context &context, const char *name, const char *desc, QueryType verifier);
493 void test(tcu::ResultCollector &result);
494 };
495
VertexBindingBufferCase(Context & context,const char * name,const char * desc,QueryType verifier)496 VertexBindingBufferCase::VertexBindingBufferCase(Context &context, const char *name, const char *desc,
497 QueryType verifier)
498 : IndexedCase(context, name, desc, verifier)
499 {
500 }
501
test(tcu::ResultCollector & result)502 void VertexBindingBufferCase::test(tcu::ResultCollector &result)
503 {
504 glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
505 glu::VertexArray vao(m_context.getRenderContext());
506 glu::Buffer buffer(m_context.getRenderContext());
507 glw::GLint reportedMaxBindings = -1;
508 glw::GLint maxBindings;
509
510 gl.enableLogging(true);
511
512 gl.glBindVertexArray(*vao);
513 gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &reportedMaxBindings);
514 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv");
515
516 maxBindings = de::max(16, reportedMaxBindings);
517
518 // initial
519 {
520 const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial values");
521
522 for (int binding = 0; binding < maxBindings; ++binding)
523 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, binding, 0, m_verifier);
524 }
525
526 // is part of vao
527 {
528 const tcu::ScopedLogSection section(m_testCtx.getLog(), "vao", "VAO state");
529 glu::VertexArray otherVao(m_context.getRenderContext());
530 glu::Buffer otherBuffer(m_context.getRenderContext());
531
532 // set to value A in vao1
533 gl.glBindVertexBuffer(1, *buffer, 0, 32);
534 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
535
536 // set to value B in vao2
537 gl.glBindVertexArray(*otherVao);
538 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
539 gl.glBindVertexBuffer(1, *otherBuffer, 0, 32);
540 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexBuffer");
541
542 // check value is still ok in original vao
543 gl.glBindVertexArray(*vao);
544 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glBindVertexArray");
545
546 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer, m_verifier);
547 }
548
549 // Is detached in delete from active vao and not from deactive
550 {
551 const tcu::ScopedLogSection section(m_testCtx.getLog(), "autoUnbind", "Unbind on delete");
552 glu::VertexArray otherVao(m_context.getRenderContext());
553 glw::GLuint otherBuffer = -1;
554
555 gl.glGenBuffers(1, &otherBuffer);
556
557 // set in vao1 and vao2
558 gl.glBindVertexBuffer(1, otherBuffer, 0, 32);
559 gl.glBindVertexArray(*otherVao);
560 gl.glBindVertexBuffer(1, otherBuffer, 0, 32);
561
562 // delete buffer. This unbinds it from active (vao2) but not from unactive
563 gl.glDeleteBuffers(1, &otherBuffer);
564 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, 0, m_verifier);
565
566 gl.glBindVertexArray(*vao);
567 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, otherBuffer, m_verifier);
568 }
569 }
570
571 class MixedVertexBindingDivisorCase : public IndexedCase
572 {
573 public:
574 MixedVertexBindingDivisorCase(Context &context, const char *name, const char *desc);
575 void test(tcu::ResultCollector &result);
576 };
577
MixedVertexBindingDivisorCase(Context & context,const char * name,const char * desc)578 MixedVertexBindingDivisorCase::MixedVertexBindingDivisorCase(Context &context, const char *name, const char *desc)
579 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
580 {
581 }
582
test(tcu::ResultCollector & result)583 void MixedVertexBindingDivisorCase::test(tcu::ResultCollector &result)
584 {
585 glu::CallLogWrapper gl(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
586 glu::VertexArray vao(m_context.getRenderContext());
587
588 gl.enableLogging(true);
589
590 gl.glBindVertexArray(*vao);
591 gl.glVertexAttribDivisor(1, 4);
592 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_DIVISOR, 1, 4, m_verifier);
593 }
594
595 class MixedVertexBindingOffsetCase : public IndexedCase
596 {
597 public:
598 MixedVertexBindingOffsetCase(Context &context, const char *name, const char *desc);
599 void test(tcu::ResultCollector &result);
600 };
601
MixedVertexBindingOffsetCase(Context & context,const char * name,const char * desc)602 MixedVertexBindingOffsetCase::MixedVertexBindingOffsetCase(Context &context, const char *name, const char *desc)
603 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
604 {
605 }
606
test(tcu::ResultCollector & result)607 void MixedVertexBindingOffsetCase::test(tcu::ResultCollector &result)
608 {
609 glu::RenderContext &renderContext = m_context.getRenderContext();
610 glu::CallLogWrapper gl(renderContext.getFunctions(), m_testCtx.getLog());
611 glu::Buffer buffer(renderContext);
612 uint32_t vao = 0;
613
614 gl.enableLogging(true);
615
616 if (!glu::isContextTypeES(renderContext.getType()))
617 {
618 gl.glGenVertexArrays(1, &vao);
619 gl.glBindVertexArray(vao);
620 }
621
622 gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
623 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, glu::BufferOffsetAsPointer(12));
624
625 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_OFFSET, 1, 12, m_verifier);
626
627 if (vao)
628 gl.glDeleteVertexArrays(1, &vao);
629 }
630
631 class MixedVertexBindingStrideCase : public IndexedCase
632 {
633 public:
634 MixedVertexBindingStrideCase(Context &context, const char *name, const char *desc);
635 void test(tcu::ResultCollector &result);
636 };
637
MixedVertexBindingStrideCase(Context & context,const char * name,const char * desc)638 MixedVertexBindingStrideCase::MixedVertexBindingStrideCase(Context &context, const char *name, const char *desc)
639 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
640 {
641 }
642
test(tcu::ResultCollector & result)643 void MixedVertexBindingStrideCase::test(tcu::ResultCollector &result)
644 {
645 glu::RenderContext &renderContext = m_context.getRenderContext();
646 glu::CallLogWrapper gl(renderContext.getFunctions(), m_testCtx.getLog());
647 glu::Buffer buffer(renderContext);
648 uint32_t vao = 0;
649
650 gl.enableLogging(true);
651
652 if (!glu::isContextTypeES(renderContext.getType()))
653 {
654 gl.glGenVertexArrays(1, &vao);
655 gl.glBindVertexArray(vao);
656 }
657
658 gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
659 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 12, 0);
660 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 12, m_verifier);
661
662 // test effectiveStride
663 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
664 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_STRIDE, 1, 16, m_verifier);
665
666 if (vao)
667 gl.glDeleteVertexArrays(1, &vao);
668 }
669
670 class MixedVertexBindingBufferCase : public IndexedCase
671 {
672 public:
673 MixedVertexBindingBufferCase(Context &context, const char *name, const char *desc);
674 void test(tcu::ResultCollector &result);
675 };
676
MixedVertexBindingBufferCase(Context & context,const char * name,const char * desc)677 MixedVertexBindingBufferCase::MixedVertexBindingBufferCase(Context &context, const char *name, const char *desc)
678 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
679 {
680 }
681
test(tcu::ResultCollector & result)682 void MixedVertexBindingBufferCase::test(tcu::ResultCollector &result)
683 {
684 glu::RenderContext &renderContext = m_context.getRenderContext();
685 glu::CallLogWrapper gl(renderContext.getFunctions(), m_testCtx.getLog());
686 glu::Buffer buffer(renderContext);
687 uint32_t vao = 0;
688
689 gl.enableLogging(true);
690
691 if (!glu::isContextTypeES(renderContext.getType()))
692 {
693 gl.glGenVertexArrays(1, &vao);
694 gl.glBindVertexArray(vao);
695 }
696
697 gl.glBindBuffer(GL_ARRAY_BUFFER, *buffer);
698 gl.glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
699 verifyStateIndexedInteger(result, gl, GL_VERTEX_BINDING_BUFFER, 1, *buffer, m_verifier);
700
701 if (vao)
702 gl.glDeleteVertexArrays(1, &vao);
703 }
704
705 } // namespace
706
VertexAttributeBindingStateQueryTests(Context & context)707 VertexAttributeBindingStateQueryTests::VertexAttributeBindingStateQueryTests(Context &context)
708 : TestCaseGroup(context, "vertex_attribute_binding", "Query vertex attribute binding state.")
709 {
710 }
711
~VertexAttributeBindingStateQueryTests(void)712 VertexAttributeBindingStateQueryTests::~VertexAttributeBindingStateQueryTests(void)
713 {
714 }
715
init(void)716 void VertexAttributeBindingStateQueryTests::init(void)
717 {
718 tcu::TestCaseGroup *const attributeGroup = new TestCaseGroup(m_context, "vertex_attrib", "Vertex attribute state");
719 tcu::TestCaseGroup *const indexedGroup = new TestCaseGroup(m_context, "indexed", "Indexed state");
720
721 addChild(attributeGroup);
722 addChild(indexedGroup);
723
724 // .vertex_attrib
725 {
726 static const struct Verifier
727 {
728 const char *suffix;
729 QueryType type;
730 } verifiers[] = {
731 {"", QUERY_ATTRIBUTE_INTEGER}, // avoid renaming tests
732 {"_getvertexattribfv", QUERY_ATTRIBUTE_FLOAT},
733 {"_getvertexattribiiv", QUERY_ATTRIBUTE_PURE_INTEGER},
734 {"_getvertexattribiuiv", QUERY_ATTRIBUTE_PURE_UNSIGNED_INTEGER},
735 };
736
737 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
738 {
739 attributeGroup->addChild(new AttributeBindingCase(
740 m_context, (std::string("vertex_attrib_binding") + verifiers[verifierNdx].suffix).c_str(),
741 "Test VERTEX_ATTRIB_BINDING", verifiers[verifierNdx].type));
742 attributeGroup->addChild(new AttributeRelativeOffsetCase(
743 m_context, (std::string("vertex_attrib_relative_offset") + verifiers[verifierNdx].suffix).c_str(),
744 "Test VERTEX_ATTRIB_RELATIVE_OFFSET", verifiers[verifierNdx].type));
745 }
746 }
747
748 // .indexed
749 {
750 static const struct Verifier
751 {
752 const char *name;
753 QueryType type;
754 } verifiers[] = {
755 {"getintegeri", QUERY_INDEXED_INTEGER},
756 {"getintegeri64", QUERY_INDEXED_INTEGER64},
757 {"getboolean", QUERY_INDEXED_BOOLEAN},
758 };
759
760 // states
761
762 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)
763 {
764 indexedGroup->addChild(new VertexBindingDivisorCase(
765 m_context, (std::string("vertex_binding_divisor_") + verifiers[verifierNdx].name).c_str(),
766 "Test VERTEX_BINDING_DIVISOR", verifiers[verifierNdx].type));
767 indexedGroup->addChild(new VertexBindingOffsetCase(
768 m_context, (std::string("vertex_binding_offset_") + verifiers[verifierNdx].name).c_str(),
769 "Test VERTEX_BINDING_OFFSET", verifiers[verifierNdx].type));
770 indexedGroup->addChild(new VertexBindingStrideCase(
771 m_context, (std::string("vertex_binding_stride_") + verifiers[verifierNdx].name).c_str(),
772 "Test VERTEX_BINDING_STRIDE", verifiers[verifierNdx].type));
773 indexedGroup->addChild(new VertexBindingBufferCase(
774 m_context, (std::string("vertex_binding_buffer_") + verifiers[verifierNdx].name).c_str(),
775 "Test VERTEX_BINDING_BUFFER", verifiers[verifierNdx].type));
776 }
777
778 // mixed apis
779
780 indexedGroup->addChild(new MixedVertexBindingDivisorCase(m_context, "vertex_binding_divisor_mixed",
781 "Test VERTEX_BINDING_DIVISOR"));
782 indexedGroup->addChild(
783 new MixedVertexBindingOffsetCase(m_context, "vertex_binding_offset_mixed", "Test VERTEX_BINDING_OFFSET"));
784 indexedGroup->addChild(
785 new MixedVertexBindingStrideCase(m_context, "vertex_binding_stride_mixed", "Test VERTEX_BINDING_STRIDE"));
786 indexedGroup->addChild(
787 new MixedVertexBindingBufferCase(m_context, "vertex_binding_buffer_mixed", "Test VERTEX_BINDING_BUFFER"));
788 }
789 }
790
791 } // namespace Functional
792 } // namespace gles31
793 } // namespace deqp
794