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, QueryType verifier)
158 : AttributeCase(context, name, desc, verifier)
159 {
160 }
161
test(tcu::ResultCollector & result)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
IndexedCase(Context & context,const char * name,const char * desc,QueryType verifier)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
iterate(void)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
VertexBindingDivisorCase(Context & context,const char * name,const char * desc,QueryType verifier)259 VertexBindingDivisorCase::VertexBindingDivisorCase (Context& context, const char* name, const char* desc, QueryType verifier)
260 : IndexedCase(context, name, desc, verifier)
261 {
262 }
263
test(tcu::ResultCollector & result)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
VertexBindingOffsetCase(Context & context,const char * name,const char * desc,QueryType verifier)336 VertexBindingOffsetCase::VertexBindingOffsetCase (Context& context, const char* name, const char* desc, QueryType verifier)
337 : IndexedCase(context, name, desc, verifier)
338 {
339 }
340
test(tcu::ResultCollector & result)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
VertexBindingStrideCase(Context & context,const char * name,const char * desc,QueryType verifier)414 VertexBindingStrideCase::VertexBindingStrideCase (Context& context, const char* name, const char* desc, QueryType verifier)
415 : IndexedCase(context, name, desc, verifier)
416 {
417 }
418
test(tcu::ResultCollector & result)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
VertexBindingBufferCase(Context & context,const char * name,const char * desc,QueryType verifier)492 VertexBindingBufferCase::VertexBindingBufferCase (Context& context, const char* name, const char* desc, QueryType verifier)
493 : IndexedCase(context, name, desc, verifier)
494 {
495 }
496
test(tcu::ResultCollector & result)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
MixedVertexBindingDivisorCase(Context & context,const char * name,const char * desc)573 MixedVertexBindingDivisorCase::MixedVertexBindingDivisorCase (Context& context, const char* name, const char* desc)
574 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
575 {
576 }
577
test(tcu::ResultCollector & result)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
MixedVertexBindingOffsetCase(Context & context,const char * name,const char * desc)597 MixedVertexBindingOffsetCase::MixedVertexBindingOffsetCase (Context& context, const char* name, const char* desc)
598 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
599 {
600 }
601
test(tcu::ResultCollector & result)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
MixedVertexBindingStrideCase(Context & context,const char * name,const char * desc)622 MixedVertexBindingStrideCase::MixedVertexBindingStrideCase (Context& context, const char* name, const char* desc)
623 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
624 {
625 }
626
test(tcu::ResultCollector & result)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
MixedVertexBindingBufferCase(Context & context,const char * name,const char * desc)650 MixedVertexBindingBufferCase::MixedVertexBindingBufferCase (Context& context, const char* name, const char* desc)
651 : IndexedCase(context, name, desc, QUERY_INDEXED_INTEGER)
652 {
653 }
654
test(tcu::ResultCollector & result)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
VertexAttributeBindingStateQueryTests(Context & context)669 VertexAttributeBindingStateQueryTests::VertexAttributeBindingStateQueryTests (Context& context)
670 : TestCaseGroup(context, "vertex_attribute_binding", "Query vertex attribute binding state.")
671 {
672 }
673
~VertexAttributeBindingStateQueryTests(void)674 VertexAttributeBindingStateQueryTests::~VertexAttributeBindingStateQueryTests (void)
675 {
676 }
677
init(void)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
742