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