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, glu::BufferOffsetAsPointer(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