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