1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Vertex array object tests
22 *//*--------------------------------------------------------------------*/
23 #include "es3fVertexArrayObjectTests.hpp"
25 #include "gluShaderProgram.hpp"
26 #include "gluPixelTransfer.hpp"
27 #include "gluRenderContext.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuImageCompare.hpp"
31 #include "tcuSurface.hpp"
32 #include "tcuRenderTarget.hpp"
34 #include "deRandom.hpp"
71 struct VertexArrayState
73 VertexArrayState (void);
75 vector<Attribute> attributes;
76 int elementArrayBuffer;
79 VertexArrayState::VertexArrayState (void)
80 : elementArrayBuffer(-1)
84 Attribute::Attribute (void)
92 , normalized (GL_FALSE)
120 bool useDrawElements;
126 VertexArrayState state;
127 VertexArrayState vao;
128 vector<BufferSpec> buffers;
134 , useDrawElements (false)
135 , indexType (GL_NONE)
145 class VertexArrayObjectTest : public TestCase
149 VertexArrayObjectTest (Context& context, const Spec& spec, const char* name, const char* description);
150 ~VertexArrayObjectTest (void);
151 virtual void init (void);
152 virtual void deinit (void);
153 virtual IterateResult iterate (void);
158 vector<GLuint> m_buffers;
159 glu::ShaderProgram* m_vaoProgram;
160 glu::ShaderProgram* m_stateProgram;
164 void logVertexArrayState (tcu::TestLog& log, const VertexArrayState& state, const std::string& msg);
165 deUint8* createRandomBufferData (const BufferSpec& buffer);
166 deUint8* generateIndices (void);
167 glu::ShaderProgram* createProgram (const VertexArrayState& state);
168 void setState (const VertexArrayState& state);
169 void render (tcu::Surface& vaoResult, tcu::Surface& defaultResult);
170 void makeDrawCall (const VertexArrayState& state);
171 void genReferences (tcu::Surface& vaoRef, tcu::Surface& defaultRef);
173 VertexArrayObjectTest (const VertexArrayObjectTest&);
174 VertexArrayObjectTest& operator= (const VertexArrayObjectTest&);
177 VertexArrayObjectTest::VertexArrayObjectTest (Context& context, const Spec& spec, const char* name, const char* description)
178 : TestCase (context, name, description)
180 , m_log (context.getTestContext().getLog())
181 , m_vaoProgram (NULL)
182 , m_stateProgram (NULL)
183 , m_random (deStringHash(name))
186 // Makes zero to zero mapping for buffers
187 m_buffers.push_back(0);
190 VertexArrayObjectTest::~VertexArrayObjectTest (void)
194 void VertexArrayObjectTest::logVertexArrayState (tcu::TestLog& log, const VertexArrayState& state, const std::string& msg)
196 std::stringstream message;
198 message << msg << "\n";
199 message << "GL_ELEMENT_ARRAY_BUFFER : " << state.elementArrayBuffer << "\n";
201 for (int attribNdx = 0; attribNdx < (int)state.attributes.size(); attribNdx++)
204 << "attribute : " << attribNdx << "\n"
205 << "\tGL_VERTEX_ATTRIB_ARRAY_ENABLED : " << (state.attributes[attribNdx].enabled ? "GL_TRUE" : "GL_FALSE") << "\n"
206 << "\tGL_VERTEX_ATTRIB_ARRAY_SIZE : " << state.attributes[attribNdx].size << "\n"
207 << "\tGL_VERTEX_ATTRIB_ARRAY_STRIDE : " << state.attributes[attribNdx].stride << "\n"
208 << "\tGL_VERTEX_ATTRIB_ARRAY_TYPE : " << state.attributes[attribNdx].type << "\n"
209 << "\tGL_VERTEX_ATTRIB_ARRAY_NORMALIZED : " << (state.attributes[attribNdx].normalized ? "GL_TRUE" : "GL_FALSE") << "\n"
210 << "\tGL_VERTEX_ATTRIB_ARRAY_INTEGER : " << (state.attributes[attribNdx].integer ? "GL_TRUE" : "GL_FALSE") << "\n"
211 << "\tGL_VERTEX_ATTRIB_ARRAY_DIVISOR : " << state.attributes[attribNdx].divisor << "\n"
212 << "\tGL_VERTEX_ATTRIB_ARRAY_POINTER : " << state.attributes[attribNdx].offset << "\n"
213 << "\tGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : " << m_buffers[state.attributes[attribNdx].bufferNdx] << "\n";
215 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
219 void VertexArrayObjectTest::init (void)
221 // \note [mika] Index 0 is reserved for 0 buffer
222 for (int bufferNdx = 0; bufferNdx < (int)m_spec.buffers.size(); bufferNdx++)
224 deUint8* data = createRandomBufferData(m_spec.buffers[bufferNdx]);
229 GLU_CHECK_CALL(glGenBuffers(1, &buffer));
230 m_buffers.push_back(buffer);
232 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, buffer));
233 GLU_CHECK_CALL(glBufferData(GL_ARRAY_BUFFER, m_spec.buffers[bufferNdx].size, data, GL_DYNAMIC_DRAW));
234 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
244 m_vaoProgram = createProgram(m_spec.vao);
245 m_log << tcu::TestLog::Message << "Program used with Vertex Array Object" << tcu::TestLog::EndMessage;
246 m_log << *m_vaoProgram;
247 m_stateProgram = createProgram(m_spec.state);
248 m_log << tcu::TestLog::Message << "Program used with Vertex Array State" << tcu::TestLog::EndMessage;
249 m_log << *m_stateProgram;
251 if (!m_vaoProgram->isOk() || !m_stateProgram->isOk())
252 TCU_FAIL("Failed to compile shaders");
254 if (m_spec.useDrawElements && (m_spec.vao.elementArrayBuffer == 0 || m_spec.state.elementArrayBuffer == 0))
255 m_indices = generateIndices();
258 void VertexArrayObjectTest::deinit (void)
260 GLU_CHECK_CALL(glDeleteBuffers((GLsizei)m_buffers.size(), &(m_buffers[0])));
263 delete m_stateProgram;
267 deUint8* VertexArrayObjectTest::generateIndices (void)
270 switch (m_spec.indexType)
272 case GL_UNSIGNED_INT: typeSize = sizeof(GLuint); break;
273 case GL_UNSIGNED_SHORT: typeSize = sizeof(GLushort); break;
274 case GL_UNSIGNED_BYTE: typeSize = sizeof(GLubyte); break;
279 deUint8* indices = new deUint8[m_spec.indexCount * typeSize];
281 for (int i = 0; i < m_spec.indexCount; i++)
283 deUint8* pos = indices + typeSize * i;
285 switch (m_spec.indexType)
287 case GL_UNSIGNED_INT:
289 GLuint v = (GLuint)m_random.getInt(m_spec.indexRangeMin, m_spec.indexRangeMax);
290 deMemcpy(pos, &v, sizeof(v));
294 case GL_UNSIGNED_SHORT:
296 GLushort v = (GLushort)m_random.getInt(m_spec.indexRangeMin, m_spec.indexRangeMax);
297 deMemcpy(pos, &v, sizeof(v));
301 case GL_UNSIGNED_BYTE:
303 GLubyte v = (GLubyte)m_random.getInt(m_spec.indexRangeMin, m_spec.indexRangeMax);
304 deMemcpy(pos, &v, sizeof(v));
316 deUint8* VertexArrayObjectTest::createRandomBufferData (const BufferSpec& buffer)
318 deUint8* data = new deUint8[buffer.size];
322 if (buffer.stride != 0)
324 stride = buffer.stride;
330 case GL_FLOAT: stride = buffer.componentCount * (int)sizeof(GLfloat); break;
331 case GL_INT: stride = buffer.componentCount * (int)sizeof(GLint); break;
332 case GL_UNSIGNED_INT: stride = buffer.componentCount * (int)sizeof(GLuint); break;
333 case GL_SHORT: stride = buffer.componentCount * (int)sizeof(GLshort); break;
334 case GL_UNSIGNED_SHORT: stride = buffer.componentCount * (int)sizeof(GLushort); break;
335 case GL_BYTE: stride = buffer.componentCount * (int)sizeof(GLbyte); break;
336 case GL_UNSIGNED_BYTE: stride = buffer.componentCount * (int)sizeof(GLubyte); break;
346 for (int pos = 0; pos < buffer.count; pos++)
348 deUint8* componentItr = itr;
349 for (int componentNdx = 0; componentNdx < buffer.componentCount; componentNdx++)
355 float v = buffer.floatRangeMin + (buffer.floatRangeMax - buffer.floatRangeMin) * m_random.getFloat();
356 deMemcpy(componentItr, &v, sizeof(v));
357 componentItr += sizeof(v);
363 GLint v = m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
364 deMemcpy(componentItr, &v, sizeof(v));
365 componentItr += sizeof(v);
369 case GL_UNSIGNED_INT:
371 GLuint v = m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
372 deMemcpy(componentItr, &v, sizeof(v));
373 componentItr += sizeof(v);
379 GLshort v = (GLshort)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
380 deMemcpy(componentItr, &v, sizeof(v));
381 componentItr += sizeof(v);
385 case GL_UNSIGNED_SHORT:
387 GLushort v = (GLushort)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
388 deMemcpy(componentItr, &v, sizeof(v));
389 componentItr += sizeof(v);
395 GLbyte v = (GLbyte)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
396 deMemcpy(componentItr, &v, sizeof(v));
397 componentItr += sizeof(v);
401 case GL_UNSIGNED_BYTE:
403 GLubyte v = (GLubyte)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
404 deMemcpy(componentItr, &v, sizeof(v));
405 componentItr += sizeof(v);
420 glu::ShaderProgram* VertexArrayObjectTest::createProgram (const VertexArrayState& state)
422 std::stringstream vertexShaderStream;
423 std::stringstream value;
425 vertexShaderStream << "#version 300 es\n";
427 for (int attribNdx = 0; attribNdx < (int)state.attributes.size(); attribNdx++)
429 if (state.attributes[attribNdx].integer)
430 vertexShaderStream << "layout(location = " << attribNdx << ") in mediump ivec4 a_attrib" << attribNdx << ";\n";
432 vertexShaderStream << "layout(location = " << attribNdx << ") in mediump vec4 a_attrib" << attribNdx << ";\n";
434 if (state.attributes[attribNdx].integer)
438 switch (state.attributes[0].type)
440 case GL_SHORT: scale = (1.0f/float((1u<<14)-1u)); break;
441 case GL_UNSIGNED_SHORT: scale = (1.0f/float((1u<<15)-1u)); break;
442 case GL_INT: scale = (1.0f/float((1u<<30)-1u)); break;
443 case GL_UNSIGNED_INT: scale = (1.0f/float((1u<<31)-1u)); break;
444 case GL_BYTE: scale = (1.0f/float((1u<<6)-1u)); break;
445 case GL_UNSIGNED_BYTE: scale = (1.0f/float((1u<<7)-1u)); break;
450 value << (attribNdx != 0 ? " + " : "" ) << scale << " * vec4(a_attrib" << attribNdx << ")";
452 else if (state.attributes[attribNdx].type != GL_FLOAT && !state.attributes[attribNdx].normalized)
456 switch (state.attributes[0].type)
458 case GL_SHORT: scale = (0.5f/float((1u<<14)-1u)); break;
459 case GL_UNSIGNED_SHORT: scale = (0.5f/float((1u<<15)-1u)); break;
460 case GL_INT: scale = (0.5f/float((1u<<30)-1u)); break;
461 case GL_UNSIGNED_INT: scale = (0.5f/float((1u<<31)-1u)); break;
462 case GL_BYTE: scale = (0.5f/float((1u<<6)-1u)); break;
463 case GL_UNSIGNED_BYTE: scale = (0.5f/float((1u<<7)-1u)); break;
468 value << (attribNdx != 0 ? " + " : "" ) << scale << " * a_attrib" << attribNdx;
471 value << (attribNdx != 0 ? " + " : "" ) << "a_attrib" << attribNdx;
475 << "out mediump vec4 v_value;\n"
476 << "void main (void)\n"
478 << "\tv_value = " << value.str() << ";\n";
480 if (state.attributes[0].integer)
484 switch (state.attributes[0].type)
486 case GL_SHORT: scale = (1.0f/float((1u<<14)-1u)); break;
487 case GL_UNSIGNED_SHORT: scale = (1.0f/float((1u<<15)-1u)); break;
488 case GL_INT: scale = (1.0f/float((1u<<30)-1u)); break;
489 case GL_UNSIGNED_INT: scale = (1.0f/float((1u<<31)-1u)); break;
490 case GL_BYTE: scale = (1.0f/float((1u<<6)-1u)); break;
491 case GL_UNSIGNED_BYTE: scale = (1.0f/float((1u<<7)-1u)); break;
498 << "\tgl_Position = vec4(" << scale << " * " << "vec3(a_attrib0.xyz), 1.0);\n"
503 if (state.attributes[0].normalized || state.attributes[0].type == GL_FLOAT)
506 << "\tgl_Position = vec4(a_attrib0.xyz, 1.0);\n"
513 switch (state.attributes[0].type)
515 case GL_SHORT: scale = (1.0f/float((1u<<14)-1u)); break;
516 case GL_UNSIGNED_SHORT: scale = (1.0f/float((1u<<15)-1u)); break;
517 case GL_INT: scale = (1.0f/float((1u<<30)-1u)); break;
518 case GL_UNSIGNED_INT: scale = (1.0f/float((1u<<31)-1u)); break;
519 case GL_BYTE: scale = (1.0f/float((1u<<6)-1u)); break;
520 case GL_UNSIGNED_BYTE: scale = (1.0f/float((1u<<7)-1u)); break;
529 << "\tgl_Position = vec4(" << scale << " * " << "a_attrib0.xyz, 1.0);\n"
534 const char* fragmentShader =
536 "in mediump vec4 v_value;\n"
537 "layout(location = 0) out mediump vec4 fragColor;\n"
540 "\tfragColor = vec4(v_value.xyz, 1.0);\n"
543 return new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderStream.str(), fragmentShader));
546 void VertexArrayObjectTest::setState (const VertexArrayState& state)
548 GLU_CHECK_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffers[state.elementArrayBuffer]));
550 for (int attribNdx = 0; attribNdx < (int)state.attributes.size(); attribNdx++)
552 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_buffers[state.attributes[attribNdx].bufferNdx]));
553 if (state.attributes[attribNdx].enabled)
554 GLU_CHECK_CALL(glEnableVertexAttribArray(attribNdx));
556 GLU_CHECK_CALL(glDisableVertexAttribArray(attribNdx));
558 if (state.attributes[attribNdx].integer)
559 GLU_CHECK_CALL(glVertexAttribIPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].stride, (const GLvoid*)((GLintptr)state.attributes[attribNdx].offset)));
561 GLU_CHECK_CALL(glVertexAttribPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].normalized, state.attributes[attribNdx].stride, (const GLvoid*)((GLintptr)state.attributes[attribNdx].offset)));
563 GLU_CHECK_CALL(glVertexAttribDivisor(attribNdx, state.attributes[attribNdx].divisor));
567 void VertexArrayObjectTest::makeDrawCall (const VertexArrayState& state)
569 GLU_CHECK_CALL(glClearColor(0.7f, 0.7f, 0.7f, 1.0f));
570 GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
572 if (m_spec.useDrawElements)
574 if (state.elementArrayBuffer == 0)
576 if (m_spec.instances == 0)
577 GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, m_spec.count, m_spec.indexType, m_indices));
579 GLU_CHECK_CALL(glDrawElementsInstanced(GL_TRIANGLES, m_spec.count, m_spec.indexType, m_indices, m_spec.instances));
583 if (m_spec.instances == 0)
584 GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, m_spec.count, m_spec.indexType, (GLvoid*)((GLintptr)m_spec.indexOffset)));
586 GLU_CHECK_CALL(glDrawElementsInstanced(GL_TRIANGLES, m_spec.count, m_spec.indexType, (GLvoid*)((GLintptr)m_spec.indexOffset), m_spec.instances));
591 if (m_spec.instances == 0)
592 GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, m_spec.count));
594 GLU_CHECK_CALL(glDrawArraysInstanced(GL_TRIANGLES, 0, m_spec.count, m_spec.instances));
598 void VertexArrayObjectTest::render (tcu::Surface& vaoResult, tcu::Surface& defaultResult)
602 GLU_CHECK_CALL(glGenVertexArrays(1, &vao));
603 GLU_CHECK_CALL(glBindVertexArray(vao));
604 setState(m_spec.vao);
605 GLU_CHECK_CALL(glBindVertexArray(0));
607 setState(m_spec.state);
609 GLU_CHECK_CALL(glBindVertexArray(vao));
610 GLU_CHECK_CALL(glUseProgram(m_vaoProgram->getProgram()));
611 makeDrawCall(m_spec.vao);
612 glu::readPixels(m_context.getRenderContext(), 0, 0, vaoResult.getAccess());
613 setState(m_spec.vao);
614 GLU_CHECK_CALL(glBindVertexArray(0));
616 GLU_CHECK_CALL(glUseProgram(m_stateProgram->getProgram()));
617 makeDrawCall(m_spec.state);
618 glu::readPixels(m_context.getRenderContext(), 0, 0, defaultResult.getAccess());
621 void VertexArrayObjectTest::genReferences (tcu::Surface& vaoRef, tcu::Surface& defaultRef)
623 setState(m_spec.vao);
624 GLU_CHECK_CALL(glUseProgram(m_vaoProgram->getProgram()));
625 makeDrawCall(m_spec.vao);
626 glu::readPixels(m_context.getRenderContext(), 0, 0, vaoRef.getAccess());
628 setState(m_spec.state);
629 GLU_CHECK_CALL(glUseProgram(m_stateProgram->getProgram()));
630 makeDrawCall(m_spec.state);
631 glu::readPixels(m_context.getRenderContext(), 0, 0, defaultRef.getAccess());
634 TestCase::IterateResult VertexArrayObjectTest::iterate (void)
636 tcu::Surface vaoReference (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
637 tcu::Surface stateReference (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
639 tcu::Surface vaoResult (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
640 tcu::Surface stateResult (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
644 logVertexArrayState(m_log, m_spec.vao, "Vertex Array Object State");
645 logVertexArrayState(m_log, m_spec.state, "OpenGL Vertex Array State");
646 genReferences(stateReference, vaoReference);
647 render(stateResult, vaoResult);
649 isOk = tcu::pixelThresholdCompare (m_log, "Results", "Comparison result from rendering with Vertex Array State", stateReference, stateResult, tcu::RGBA(0,0,0,0), tcu::COMPARE_LOG_RESULT);
650 isOk = isOk && tcu::pixelThresholdCompare (m_log, "Results", "Comparison result from rendering with Vertex Array Object", vaoReference, vaoResult, tcu::RGBA(0,0,0,0), tcu::COMPARE_LOG_RESULT);
654 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
659 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
664 class MultiVertexArrayObjectTest : public TestCase
668 MultiVertexArrayObjectTest (Context& context, const char* name, const char* description);
669 ~MultiVertexArrayObjectTest (void);
670 virtual void init (void);
671 virtual void deinit (void);
672 virtual IterateResult iterate (void);
677 vector<GLuint> m_buffers;
678 glu::ShaderProgram* m_vaoProgram;
679 glu::ShaderProgram* m_stateProgram;
683 void logVertexArrayState (tcu::TestLog& log, const VertexArrayState& state, const std::string& msg);
684 deUint8* createRandomBufferData (const BufferSpec& buffer);
685 deUint8* generateIndices (void);
686 glu::ShaderProgram* createProgram (const VertexArrayState& state);
687 void setState (const VertexArrayState& state);
688 void render (tcu::Surface& vaoResult, tcu::Surface& defaultResult);
689 void makeDrawCall (const VertexArrayState& state);
690 void genReferences (tcu::Surface& vaoRef, tcu::Surface& defaultRef);
692 MultiVertexArrayObjectTest (const MultiVertexArrayObjectTest&);
693 MultiVertexArrayObjectTest& operator= (const MultiVertexArrayObjectTest&);
696 MultiVertexArrayObjectTest::MultiVertexArrayObjectTest (Context& context, const char* name, const char* description)
697 : TestCase (context, name, description)
698 , m_log (context.getTestContext().getLog())
699 , m_vaoProgram (NULL)
700 , m_stateProgram (NULL)
701 , m_random (deStringHash(name))
704 // Makes zero to zero mapping for buffers
705 m_buffers.push_back(0);
708 MultiVertexArrayObjectTest::~MultiVertexArrayObjectTest (void)
712 void MultiVertexArrayObjectTest::logVertexArrayState (tcu::TestLog& log, const VertexArrayState& state, const std::string& msg)
714 std::stringstream message;
716 message << msg << "\n";
717 message << "GL_ELEMENT_ARRAY_BUFFER : " << state.elementArrayBuffer << "\n";
719 for (int attribNdx = 0; attribNdx < (int)state.attributes.size(); attribNdx++)
722 << "attribute : " << attribNdx << "\n"
723 << "\tGL_VERTEX_ATTRIB_ARRAY_ENABLED : " << (state.attributes[attribNdx].enabled ? "GL_TRUE" : "GL_FALSE") << "\n"
724 << "\tGL_VERTEX_ATTRIB_ARRAY_SIZE : " << state.attributes[attribNdx].size << "\n"
725 << "\tGL_VERTEX_ATTRIB_ARRAY_STRIDE : " << state.attributes[attribNdx].stride << "\n"
726 << "\tGL_VERTEX_ATTRIB_ARRAY_TYPE : " << state.attributes[attribNdx].type << "\n"
727 << "\tGL_VERTEX_ATTRIB_ARRAY_NORMALIZED : " << (state.attributes[attribNdx].normalized ? "GL_TRUE" : "GL_FALSE") << "\n"
728 << "\tGL_VERTEX_ATTRIB_ARRAY_INTEGER : " << (state.attributes[attribNdx].integer ? "GL_TRUE" : "GL_FALSE") << "\n"
729 << "\tGL_VERTEX_ATTRIB_ARRAY_DIVISOR : " << state.attributes[attribNdx].divisor << "\n"
730 << "\tGL_VERTEX_ATTRIB_ARRAY_POINTER : " << state.attributes[attribNdx].offset << "\n"
731 << "\t GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : " << m_buffers[state.attributes[attribNdx].bufferNdx] << "\n";
733 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
737 void MultiVertexArrayObjectTest::init (void)
741 GLU_CHECK_CALL(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attribCount));
743 m_spec.useDrawElements = false;
744 m_spec.instances = 0;
746 m_spec.indexOffset = 0;
747 m_spec.indexRangeMin = 0;
748 m_spec.indexRangeMax = 0;
749 m_spec.indexType = GL_NONE;
750 m_spec.indexCount = 0;
751 m_spec.vao.elementArrayBuffer = 0;
752 m_spec.state.elementArrayBuffer = 0;
754 for (int attribNdx = 0; attribNdx < attribCount; attribNdx++)
756 BufferSpec shortCoordBuffer48 = { 48, 2*384, 4, 0, 0, GL_SHORT, -32768, 32768, 0.0f, 0.0f };
757 m_spec.buffers.push_back(shortCoordBuffer48);
759 m_spec.state.attributes.push_back(Attribute());
760 m_spec.state.attributes[attribNdx].enabled = (m_random.getInt(0, 4) == 0) ? GL_FALSE : GL_TRUE;
761 m_spec.state.attributes[attribNdx].size = m_random.getInt(2,4);
762 m_spec.state.attributes[attribNdx].stride = 2*m_random.getInt(1, 3);
763 m_spec.state.attributes[attribNdx].type = GL_SHORT;
764 m_spec.state.attributes[attribNdx].integer = m_random.getBool();
765 m_spec.state.attributes[attribNdx].divisor = m_random.getInt(0, 1);
766 m_spec.state.attributes[attribNdx].offset = 2*m_random.getInt(0, 2);
767 m_spec.state.attributes[attribNdx].normalized = m_random.getBool();
768 m_spec.state.attributes[attribNdx].bufferNdx = attribNdx+1;
772 m_spec.state.attributes[attribNdx].divisor = 0;
773 m_spec.state.attributes[attribNdx].enabled = GL_TRUE;
774 m_spec.state.attributes[attribNdx].size = 2;
777 m_spec.vao.attributes.push_back(Attribute());
778 m_spec.vao.attributes[attribNdx].enabled = (m_random.getInt(0, 4) == 0) ? GL_FALSE : GL_TRUE;
779 m_spec.vao.attributes[attribNdx].size = m_random.getInt(2,4);
780 m_spec.vao.attributes[attribNdx].stride = 2*m_random.getInt(1, 3);
781 m_spec.vao.attributes[attribNdx].type = GL_SHORT;
782 m_spec.vao.attributes[attribNdx].integer = m_random.getBool();
783 m_spec.vao.attributes[attribNdx].divisor = m_random.getInt(0, 1);
784 m_spec.vao.attributes[attribNdx].offset = 2*m_random.getInt(0, 2);
785 m_spec.vao.attributes[attribNdx].normalized = m_random.getBool();
786 m_spec.vao.attributes[attribNdx].bufferNdx = attribCount - attribNdx;
790 m_spec.vao.attributes[attribNdx].divisor = 0;
791 m_spec.vao.attributes[attribNdx].enabled = GL_TRUE;
792 m_spec.vao.attributes[attribNdx].size = 2;
797 // \note [mika] Index 0 is reserved for 0 buffer
798 for (int bufferNdx = 0; bufferNdx < (int)m_spec.buffers.size(); bufferNdx++)
800 deUint8* data = createRandomBufferData(m_spec.buffers[bufferNdx]);
805 GLU_CHECK_CALL(glGenBuffers(1, &buffer));
806 m_buffers.push_back(buffer);
808 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, buffer));
809 GLU_CHECK_CALL(glBufferData(GL_ARRAY_BUFFER, m_spec.buffers[bufferNdx].size, data, GL_DYNAMIC_DRAW));
810 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
820 m_vaoProgram = createProgram(m_spec.vao);
821 m_log << tcu::TestLog::Message << "Program used with Vertex Array Object" << tcu::TestLog::EndMessage;
822 m_log << *m_vaoProgram;
823 m_stateProgram = createProgram(m_spec.state);
824 m_log << tcu::TestLog::Message << "Program used with Vertex Array State" << tcu::TestLog::EndMessage;
825 m_log << *m_stateProgram;
827 if (!m_vaoProgram->isOk() || !m_stateProgram->isOk())
828 TCU_FAIL("Failed to compile shaders");
830 if (m_spec.useDrawElements && (m_spec.vao.elementArrayBuffer == 0 || m_spec.state.elementArrayBuffer == 0))
831 m_indices = generateIndices();
834 void MultiVertexArrayObjectTest::deinit (void)
836 GLU_CHECK_CALL(glDeleteBuffers((GLsizei)m_buffers.size(), &(m_buffers[0])));
839 delete m_stateProgram;
843 deUint8* MultiVertexArrayObjectTest::generateIndices (void)
846 switch (m_spec.indexType)
848 case GL_UNSIGNED_INT: typeSize = sizeof(GLuint); break;
849 case GL_UNSIGNED_SHORT: typeSize = sizeof(GLushort); break;
850 case GL_UNSIGNED_BYTE: typeSize = sizeof(GLubyte); break;
855 deUint8* indices = new deUint8[m_spec.indexCount * typeSize];
857 for (int i = 0; i < m_spec.indexCount; i++)
859 deUint8* pos = indices + typeSize * i;
861 switch (m_spec.indexType)
863 case GL_UNSIGNED_INT:
865 GLuint v = (GLuint)m_random.getInt(m_spec.indexRangeMin, m_spec.indexRangeMax);
866 deMemcpy(pos, &v, sizeof(v));
870 case GL_UNSIGNED_SHORT:
872 GLushort v = (GLushort)m_random.getInt(m_spec.indexRangeMin, m_spec.indexRangeMax);
873 deMemcpy(pos, &v, sizeof(v));
877 case GL_UNSIGNED_BYTE:
879 GLubyte v = (GLubyte)m_random.getInt(m_spec.indexRangeMin, m_spec.indexRangeMax);
880 deMemcpy(pos, &v, sizeof(v));
892 deUint8* MultiVertexArrayObjectTest::createRandomBufferData (const BufferSpec& buffer)
894 deUint8* data = new deUint8[buffer.size];
898 if (buffer.stride != 0)
900 stride = buffer.stride;
906 case GL_FLOAT: stride = buffer.componentCount * (int)sizeof(GLfloat); break;
907 case GL_INT: stride = buffer.componentCount * (int)sizeof(GLint); break;
908 case GL_UNSIGNED_INT: stride = buffer.componentCount * (int)sizeof(GLuint); break;
909 case GL_SHORT: stride = buffer.componentCount * (int)sizeof(GLshort); break;
910 case GL_UNSIGNED_SHORT: stride = buffer.componentCount * (int)sizeof(GLushort); break;
911 case GL_BYTE: stride = buffer.componentCount * (int)sizeof(GLbyte); break;
912 case GL_UNSIGNED_BYTE: stride = buffer.componentCount * (int)sizeof(GLubyte); break;
922 for (int pos = 0; pos < buffer.count; pos++)
924 deUint8* componentItr = itr;
925 for (int componentNdx = 0; componentNdx < buffer.componentCount; componentNdx++)
931 float v = buffer.floatRangeMin + (buffer.floatRangeMax - buffer.floatRangeMin) * m_random.getFloat();
932 deMemcpy(componentItr, &v, sizeof(v));
933 componentItr += sizeof(v);
939 GLint v = m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
940 deMemcpy(componentItr, &v, sizeof(v));
941 componentItr += sizeof(v);
945 case GL_UNSIGNED_INT:
947 GLuint v = (GLuint)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
948 deMemcpy(componentItr, &v, sizeof(v));
949 componentItr += sizeof(v);
955 GLshort v = (GLshort)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
956 deMemcpy(componentItr, &v, sizeof(v));
957 componentItr += sizeof(v);
961 case GL_UNSIGNED_SHORT:
963 GLushort v = (GLushort)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
964 deMemcpy(componentItr, &v, sizeof(v));
965 componentItr += sizeof(v);
971 GLbyte v = (GLbyte)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
972 deMemcpy(componentItr, &v, sizeof(v));
973 componentItr += sizeof(v);
977 case GL_UNSIGNED_BYTE:
979 GLubyte v = (GLubyte)m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
980 deMemcpy(componentItr, &v, sizeof(v));
981 componentItr += sizeof(v);
996 glu::ShaderProgram* MultiVertexArrayObjectTest::createProgram (const VertexArrayState& state)
998 std::stringstream vertexShaderStream;
999 std::stringstream value;
1001 vertexShaderStream << "#version 300 es\n";
1003 for (int attribNdx = 0; attribNdx < (int)state.attributes.size(); attribNdx++)
1005 if (state.attributes[attribNdx].integer)
1006 vertexShaderStream << "layout(location = " << attribNdx << ") in mediump ivec4 a_attrib" << attribNdx << ";\n";
1008 vertexShaderStream << "layout(location = " << attribNdx << ") in mediump vec4 a_attrib" << attribNdx << ";\n";
1010 if (state.attributes[attribNdx].integer)
1014 switch (state.attributes[0].type)
1016 case GL_SHORT: scale = (1.0f/float((1u<<14)-1u)); break;
1017 case GL_UNSIGNED_SHORT: scale = (1.0f/float((1u<<15)-1u)); break;
1018 case GL_INT: scale = (1.0f/float((1u<<30)-1u)); break;
1019 case GL_UNSIGNED_INT: scale = (1.0f/float((1u<<31)-1u)); break;
1020 case GL_BYTE: scale = (1.0f/float((1u<<6)-1u)); break;
1021 case GL_UNSIGNED_BYTE: scale = (1.0f/float((1u<<7)-1u)); break;
1024 DE_ASSERT(DE_FALSE);
1026 value << (attribNdx != 0 ? " + " : "" ) << scale << " * vec4(a_attrib" << attribNdx << ")";
1028 else if (state.attributes[attribNdx].type != GL_FLOAT && !state.attributes[attribNdx].normalized)
1032 switch (state.attributes[0].type)
1034 case GL_SHORT: scale = (0.5f/float((1u<<14)-1u)); break;
1035 case GL_UNSIGNED_SHORT: scale = (0.5f/float((1u<<15)-1u)); break;
1036 case GL_INT: scale = (0.5f/float((1u<<30)-1u)); break;
1037 case GL_UNSIGNED_INT: scale = (0.5f/float((1u<<31)-1u)); break;
1038 case GL_BYTE: scale = (0.5f/float((1u<<6)-1u)); break;
1039 case GL_UNSIGNED_BYTE: scale = (0.5f/float((1u<<7)-1u)); break;
1042 DE_ASSERT(DE_FALSE);
1044 value << (attribNdx != 0 ? " + " : "" ) << scale << " * a_attrib" << attribNdx;
1047 value << (attribNdx != 0 ? " + " : "" ) << "a_attrib" << attribNdx;
1051 << "out mediump vec4 v_value;\n"
1052 << "void main (void)\n"
1054 << "\tv_value = " << value.str() << ";\n";
1056 if (state.attributes[0].integer)
1060 switch (state.attributes[0].type)
1062 case GL_SHORT: scale = (1.0f/float((1u<<14)-1u)); break;
1063 case GL_UNSIGNED_SHORT: scale = (1.0f/float((1u<<15)-1u)); break;
1064 case GL_INT: scale = (1.0f/float((1u<<30)-1u)); break;
1065 case GL_UNSIGNED_INT: scale = (1.0f/float((1u<<31)-1u)); break;
1066 case GL_BYTE: scale = (1.0f/float((1u<<6)-1u)); break;
1067 case GL_UNSIGNED_BYTE: scale = (1.0f/float((1u<<7)-1u)); break;
1071 DE_ASSERT(DE_FALSE);
1075 << "\tgl_Position = vec4(" << scale << " * " << "a_attrib0.xyz, 1.0);\n"
1080 if (state.attributes[0].normalized || state.attributes[0].type == GL_FLOAT)
1083 << "\tgl_Position = vec4(a_attrib0.xyz, 1.0);\n"
1090 switch (state.attributes[0].type)
1092 case GL_SHORT: scale = (1.0f/float((1u<<14)-1u)); break;
1093 case GL_UNSIGNED_SHORT: scale = (1.0f/float((1u<<15)-1u)); break;
1094 case GL_INT: scale = (1.0f/float((1u<<30)-1u)); break;
1095 case GL_UNSIGNED_INT: scale = (1.0f/float((1u<<31)-1u)); break;
1096 case GL_BYTE: scale = (1.0f/float((1u<<6)-1u)); break;
1097 case GL_UNSIGNED_BYTE: scale = (1.0f/float((1u<<7)-1u)); break;
1100 DE_ASSERT(DE_FALSE);
1106 << "\tgl_Position = vec4(" << scale << " * " << "vec3(a_attrib0.xyz), 1.0);\n"
1111 const char* fragmentShader =
1113 "in mediump vec4 v_value;\n"
1114 "layout(location = 0) out mediump vec4 fragColor;\n"
1115 "void main (void)\n"
1117 "\tfragColor = vec4(v_value.xyz, 1.0);\n"
1120 return new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderStream.str(), fragmentShader));
1123 void MultiVertexArrayObjectTest::setState (const VertexArrayState& state)
1125 GLU_CHECK_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffers[state.elementArrayBuffer]));
1127 for (int attribNdx = 0; attribNdx < (int)state.attributes.size(); attribNdx++)
1129 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_buffers[state.attributes[attribNdx].bufferNdx]));
1130 if (state.attributes[attribNdx].enabled)
1131 GLU_CHECK_CALL(glEnableVertexAttribArray(attribNdx));
1133 GLU_CHECK_CALL(glDisableVertexAttribArray(attribNdx));
1135 if (state.attributes[attribNdx].integer)
1136 GLU_CHECK_CALL(glVertexAttribIPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].stride, (const GLvoid*)((GLintptr)state.attributes[attribNdx].offset)));
1138 GLU_CHECK_CALL(glVertexAttribPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].normalized, state.attributes[attribNdx].stride, (const GLvoid*)((GLintptr)state.attributes[attribNdx].offset)));
1140 GLU_CHECK_CALL(glVertexAttribDivisor(attribNdx, state.attributes[attribNdx].divisor));
1144 void MultiVertexArrayObjectTest::makeDrawCall (const VertexArrayState& state)
1146 GLU_CHECK_CALL(glClearColor(0.7f, 0.7f, 0.7f, 1.0f));
1147 GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
1149 if (m_spec.useDrawElements)
1151 if (state.elementArrayBuffer == 0)
1153 if (m_spec.instances == 0)
1154 GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, m_spec.count, m_spec.indexType, m_indices));
1156 GLU_CHECK_CALL(glDrawElementsInstanced(GL_TRIANGLES, m_spec.count, m_spec.indexType, m_indices, m_spec.instances));
1160 if (m_spec.instances == 0)
1161 GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, m_spec.count, m_spec.indexType, (GLvoid*)((GLintptr)m_spec.indexOffset)));
1163 GLU_CHECK_CALL(glDrawElementsInstanced(GL_TRIANGLES, m_spec.count, m_spec.indexType, (GLvoid*)((GLintptr)m_spec.indexOffset), m_spec.instances));
1168 if (m_spec.instances == 0)
1169 GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, m_spec.count));
1171 GLU_CHECK_CALL(glDrawArraysInstanced(GL_TRIANGLES, 0, m_spec.count, m_spec.instances));
1175 void MultiVertexArrayObjectTest::render (tcu::Surface& vaoResult, tcu::Surface& defaultResult)
1179 GLU_CHECK_CALL(glGenVertexArrays(1, &vao));
1180 GLU_CHECK_CALL(glBindVertexArray(vao));
1181 setState(m_spec.vao);
1182 GLU_CHECK_CALL(glBindVertexArray(0));
1184 setState(m_spec.state);
1186 GLU_CHECK_CALL(glBindVertexArray(vao));
1187 GLU_CHECK_CALL(glUseProgram(m_vaoProgram->getProgram()));
1188 makeDrawCall(m_spec.vao);
1189 glu::readPixels(m_context.getRenderContext(), 0, 0, vaoResult.getAccess());
1190 setState(m_spec.vao);
1191 GLU_CHECK_CALL(glBindVertexArray(0));
1193 GLU_CHECK_CALL(glUseProgram(m_stateProgram->getProgram()));
1194 makeDrawCall(m_spec.state);
1195 glu::readPixels(m_context.getRenderContext(), 0, 0, defaultResult.getAccess());
1198 void MultiVertexArrayObjectTest::genReferences (tcu::Surface& vaoRef, tcu::Surface& defaultRef)
1200 setState(m_spec.vao);
1201 GLU_CHECK_CALL(glUseProgram(m_vaoProgram->getProgram()));
1202 makeDrawCall(m_spec.vao);
1203 glu::readPixels(m_context.getRenderContext(), 0, 0, vaoRef.getAccess());
1205 setState(m_spec.state);
1206 GLU_CHECK_CALL(glUseProgram(m_stateProgram->getProgram()));
1207 makeDrawCall(m_spec.state);
1208 glu::readPixels(m_context.getRenderContext(), 0, 0, defaultRef.getAccess());
1211 TestCase::IterateResult MultiVertexArrayObjectTest::iterate (void)
1213 tcu::Surface vaoReference (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
1214 tcu::Surface stateReference (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
1216 tcu::Surface vaoResult (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
1217 tcu::Surface stateResult (m_context.getRenderContext().getRenderTarget().getWidth(), m_context.getRenderContext().getRenderTarget().getHeight());
1221 logVertexArrayState(m_log, m_spec.vao, "Vertex Array Object State");
1222 logVertexArrayState(m_log, m_spec.state, "OpenGL Vertex Array State");
1223 genReferences(stateReference, vaoReference);
1224 render(stateResult, vaoResult);
1226 isOk = tcu::pixelThresholdCompare (m_log, "Results", "Comparison result from rendering with Vertex Array State", stateReference, stateResult, tcu::RGBA(0,0,0,0), tcu::COMPARE_LOG_RESULT);
1227 isOk = isOk && tcu::pixelThresholdCompare (m_log, "Results", "Comparison result from rendering with Vertex Array Object", vaoReference, vaoResult, tcu::RGBA(0,0,0,0), tcu::COMPARE_LOG_RESULT);
1231 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1236 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1241 VertexArrayObjectTestGroup::VertexArrayObjectTestGroup (Context& context)
1242 : TestCaseGroup(context, "vertex_array_objects", "Vertex array object test cases")
1246 VertexArrayObjectTestGroup::~VertexArrayObjectTestGroup (void)
1250 void VertexArrayObjectTestGroup::init (void)
1252 BufferSpec floatCoordBuffer48_1 = { 48, 384, 2, 0, 0, GL_FLOAT, 0, 0, -1.0f, 1.0f };
1253 BufferSpec floatCoordBuffer48_2 = { 48, 384, 2, 0, 0, GL_FLOAT, 0, 0, -1.0f, 1.0f };
1255 BufferSpec shortCoordBuffer48 = { 48, 192, 2, 0, 0, GL_SHORT, -32768, 32768, 0.0f, 0.0f };
1261 VertexArrayState state;
1263 state.attributes.push_back(Attribute());
1265 state.attributes[0].enabled = true;
1266 state.attributes[0].size = 2;
1267 state.attributes[0].stride = 0;
1268 state.attributes[0].type = GL_FLOAT;
1269 state.attributes[0].integer = GL_FALSE;
1270 state.attributes[0].divisor = 0;
1271 state.attributes[0].offset = 0;
1272 state.attributes[0].normalized = GL_FALSE;
1274 state.elementArrayBuffer = 0;
1276 spec.buffers.push_back(floatCoordBuffer48_1);
1277 spec.buffers.push_back(floatCoordBuffer48_2);
1279 spec.useDrawElements = false;
1284 spec.indexOffset = 0;
1285 spec.indexRangeMin = 0;
1286 spec.indexRangeMax = 0;
1287 spec.indexType = GL_NONE;
1288 spec.indexCount = 0;
1290 spec.state.attributes[0].bufferNdx = 1;
1291 spec.vao.attributes[0].bufferNdx = 2;
1292 addChild(new VertexArrayObjectTest(m_context, spec, "diff_buffer", "diff_buffer"));
1298 VertexArrayState state;
1300 state.attributes.push_back(Attribute());
1302 state.attributes[0].enabled = true;
1303 state.attributes[0].size = 2;
1304 state.attributes[0].stride = 0;
1305 state.attributes[0].type = GL_FLOAT;
1306 state.attributes[0].integer = GL_FALSE;
1307 state.attributes[0].divisor = 0;
1308 state.attributes[0].offset = 0;
1309 state.attributes[0].normalized = GL_FALSE;
1310 state.attributes[0].bufferNdx = 1;
1312 state.elementArrayBuffer = 0;
1314 spec.buffers.push_back(floatCoordBuffer48_1);
1316 spec.useDrawElements = false;
1321 spec.indexOffset = 0;
1322 spec.indexRangeMin = 0;
1323 spec.indexRangeMax = 0;
1324 spec.indexType = GL_NONE;
1325 spec.indexCount = 0;
1327 spec.state.attributes[0].size = 2;
1328 spec.vao.attributes[0].size = 3;
1329 addChild(new VertexArrayObjectTest(m_context, spec, "diff_size", "diff_size"));
1336 VertexArrayState state;
1338 state.attributes.push_back(Attribute());
1340 state.attributes[0].enabled = true;
1341 state.attributes[0].size = 2;
1342 state.attributes[0].stride = 0;
1343 state.attributes[0].type = GL_SHORT;
1344 state.attributes[0].integer = GL_FALSE;
1345 state.attributes[0].divisor = 0;
1346 state.attributes[0].offset = 0;
1347 state.attributes[0].normalized = GL_TRUE;
1348 state.attributes[0].bufferNdx = 1;
1350 state.elementArrayBuffer = 0;
1352 spec.buffers.push_back(shortCoordBuffer48);
1354 spec.useDrawElements = false;
1359 spec.indexOffset = 0;
1360 spec.indexRangeMin = 0;
1361 spec.indexRangeMax = 0;
1362 spec.indexType = GL_NONE;
1363 spec.indexCount = 0;
1365 spec.vao.attributes[0].stride = 2;
1366 spec.state.attributes[0].stride = 4;
1367 addChild(new VertexArrayObjectTest(m_context, spec, "diff_stride", "diff_stride"));
1374 VertexArrayState state;
1376 state.attributes.push_back(Attribute());
1378 state.attributes[0].enabled = true;
1379 state.attributes[0].size = 2;
1380 state.attributes[0].stride = 0;
1381 state.attributes[0].type = GL_SHORT;
1382 state.attributes[0].integer = GL_FALSE;
1383 state.attributes[0].divisor = 0;
1384 state.attributes[0].offset = 0;
1385 state.attributes[0].normalized = GL_TRUE;
1386 state.attributes[0].bufferNdx = 1;
1388 state.elementArrayBuffer = 0;
1390 spec.buffers.push_back(shortCoordBuffer48);
1392 spec.useDrawElements = false;
1397 spec.indexOffset = 0;
1398 spec.indexRangeMin = 0;
1399 spec.indexRangeMax = 0;
1400 spec.indexType = GL_NONE;
1401 spec.indexCount = 0;
1403 spec.vao.attributes[0].type = GL_SHORT;
1404 spec.state.attributes[0].type = GL_BYTE;
1405 addChild(new VertexArrayObjectTest(m_context, spec, "diff_type", "diff_type"));
1407 // Different "integer"
1411 VertexArrayState state;
1413 state.attributes.push_back(Attribute());
1415 state.attributes[0].enabled = true;
1416 state.attributes[0].size = 2;
1417 state.attributes[0].stride = 0;
1418 state.attributes[0].type = GL_BYTE;
1419 state.attributes[0].integer = GL_TRUE;
1420 state.attributes[0].divisor = 0;
1421 state.attributes[0].offset = 0;
1422 state.attributes[0].normalized = GL_FALSE;
1423 state.attributes[0].bufferNdx = 1;
1425 state.elementArrayBuffer = 0;
1427 spec.buffers.push_back(shortCoordBuffer48);
1429 spec.useDrawElements = false;
1434 spec.indexOffset = 0;
1435 spec.indexRangeMin = 0;
1436 spec.indexRangeMax = 0;
1437 spec.indexType = GL_NONE;
1438 spec.indexCount = 0;
1440 spec.state.attributes[0].integer = GL_FALSE;
1441 spec.vao.attributes[0].integer = GL_TRUE;
1442 addChild(new VertexArrayObjectTest(m_context, spec, "diff_integer", "diff_integer"));
1444 // Different divisor
1448 VertexArrayState state;
1450 state.attributes.push_back(Attribute());
1451 state.attributes.push_back(Attribute());
1453 state.attributes[0].enabled = true;
1454 state.attributes[0].size = 2;
1455 state.attributes[0].stride = 0;
1456 state.attributes[0].type = GL_SHORT;
1457 state.attributes[0].integer = GL_FALSE;
1458 state.attributes[0].divisor = 0;
1459 state.attributes[0].offset = 0;
1460 state.attributes[0].normalized = GL_TRUE;
1461 state.attributes[0].bufferNdx = 1;
1463 state.attributes[1].enabled = true;
1464 state.attributes[1].size = 4;
1465 state.attributes[1].stride = 0;
1466 state.attributes[1].type = GL_FLOAT;
1467 state.attributes[1].integer = GL_FALSE;
1468 state.attributes[1].divisor = 0;
1469 state.attributes[1].offset = 0;
1470 state.attributes[1].normalized = GL_FALSE;
1471 state.attributes[1].bufferNdx = 2;
1473 state.elementArrayBuffer = 0;
1475 spec.buffers.push_back(shortCoordBuffer48);
1476 spec.buffers.push_back(floatCoordBuffer48_1);
1478 spec.useDrawElements = false;
1479 spec.instances = 10;
1483 spec.indexOffset = 0;
1484 spec.indexRangeMin = 0;
1485 spec.indexRangeMax = 0;
1486 spec.indexType = GL_NONE;
1487 spec.indexCount = 0;
1489 spec.vao.attributes[1].divisor = 3;
1490 spec.state.attributes[1].divisor = 2;
1492 addChild(new VertexArrayObjectTest(m_context, spec, "diff_divisor", "diff_divisor"));
1498 VertexArrayState state;
1500 state.attributes.push_back(Attribute());
1502 state.attributes[0].enabled = true;
1503 state.attributes[0].size = 2;
1504 state.attributes[0].stride = 0;
1505 state.attributes[0].type = GL_SHORT;
1506 state.attributes[0].integer = GL_FALSE;
1507 state.attributes[0].divisor = 0;
1508 state.attributes[0].offset = 0;
1509 state.attributes[0].normalized = GL_TRUE;
1510 state.attributes[0].bufferNdx = 1;
1512 state.elementArrayBuffer = 0;
1514 spec.buffers.push_back(shortCoordBuffer48);
1516 spec.useDrawElements = false;
1521 spec.indexOffset = 0;
1522 spec.indexRangeMin = 0;
1523 spec.indexRangeMax = 0;
1524 spec.indexType = GL_NONE;
1525 spec.indexCount = 0;
1527 spec.vao.attributes[0].offset = 2;
1528 spec.state.attributes[0].offset = 4;
1529 addChild(new VertexArrayObjectTest(m_context, spec, "diff_offset", "diff_offset"));
1531 // Different normalize
1535 VertexArrayState state;
1537 state.attributes.push_back(Attribute());
1539 state.attributes[0].enabled = true;
1540 state.attributes[0].size = 2;
1541 state.attributes[0].stride = 0;
1542 state.attributes[0].type = GL_SHORT;
1543 state.attributes[0].integer = GL_FALSE;
1544 state.attributes[0].divisor = 0;
1545 state.attributes[0].offset = 0;
1546 state.attributes[0].normalized = GL_TRUE;
1547 state.attributes[0].bufferNdx = 1;
1549 state.elementArrayBuffer = 0;
1551 spec.buffers.push_back(shortCoordBuffer48);
1553 spec.useDrawElements = false;
1558 spec.indexOffset = 0;
1559 spec.indexRangeMin = 0;
1560 spec.indexRangeMax = 0;
1561 spec.indexType = GL_NONE;
1562 spec.indexCount = 0;
1564 spec.vao.attributes[0].normalized = GL_TRUE;
1565 spec.state.attributes[0].normalized = GL_FALSE;;
1566 addChild(new VertexArrayObjectTest(m_context, spec, "diff_normalize", "diff_normalize"));
1568 // DrawElements with buffer / Pointer
1572 VertexArrayState state;
1574 state.attributes.push_back(Attribute());
1576 state.attributes[0].enabled = true;
1577 state.attributes[0].size = 2;
1578 state.attributes[0].stride = 0;
1579 state.attributes[0].type = GL_FLOAT;
1580 state.attributes[0].integer = GL_FALSE;
1581 state.attributes[0].divisor = 0;
1582 state.attributes[0].offset = 0;
1583 state.attributes[0].normalized = GL_TRUE;
1584 state.attributes[0].bufferNdx = 1;
1586 state.elementArrayBuffer = 0;
1588 spec.buffers.push_back(floatCoordBuffer48_1);
1590 BufferSpec indexBuffer = { 24, 192, 1, 0, 0, GL_UNSIGNED_SHORT, 0, 48, 0.0f, 0.0f };
1591 spec.buffers.push_back(indexBuffer);
1593 spec.useDrawElements = true;
1598 spec.indexOffset = 0;
1599 spec.indexRangeMin = 0;
1600 spec.indexRangeMax = 48;
1601 spec.indexType = GL_UNSIGNED_SHORT;
1602 spec.indexCount = 24;
1604 spec.state.elementArrayBuffer = 0;
1605 spec.vao.elementArrayBuffer = 2;
1606 addChild(new VertexArrayObjectTest(m_context, spec, "diff_indices", "diff_indices"));
1608 // Use all attributes
1610 addChild(new MultiVertexArrayObjectTest(m_context, "all_attributes", "all_attributes"));