1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2017 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 GL_EXT_draw_elements_base_vertex tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es31fDrawElementsBaseVertexTests.hpp"
25 #include "deRandom.hpp"
26 #include "deStringUtil.hpp"
27 #include "tcuRenderTarget.hpp"
28 #include "tcuVectorUtil.hpp"
29 #include "sglrGLContext.hpp"
30 #include "glsDrawTest.hpp"
31 #include "gluStrUtil.hpp"
32 #include "gluPixelTransfer.hpp"
33 #include "gluContextInfo.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
56 enum TestIterationType
58 TYPE_DRAW_COUNT, // !< test with 1, 5, and 25 primitives
59 TYPE_INSTANCE_COUNT, // !< test with 1, 4, and 11 instances
64 static size_t getElementCount (gls::DrawTestSpec::Primitive primitive, size_t primitiveCount)
68 case gls::DrawTestSpec::PRIMITIVE_POINTS: return primitiveCount;
69 case gls::DrawTestSpec::PRIMITIVE_TRIANGLES: return primitiveCount * 3;
70 case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: return primitiveCount + 2;
71 case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: return primitiveCount + 2;
72 case gls::DrawTestSpec::PRIMITIVE_LINES: return primitiveCount * 2;
73 case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP: return primitiveCount + 1;
74 case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP: return (primitiveCount==1) ? (2) : (primitiveCount);
75 case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: return primitiveCount * 4;
76 case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: return primitiveCount + 3;
77 case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: return primitiveCount * 6;
78 case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: return primitiveCount * 2 + 4;
85 static void addRangeElementsToSpec (gls::DrawTestSpec& spec)
87 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
90 spec.indexMax = (int)getElementCount(spec.primitive, spec.primitiveCount);
94 static void addTestIterations (gls::DrawTest* test, gls::DrawTestSpec& spec, TestIterationType type)
96 if (type == TYPE_DRAW_COUNT)
98 spec.primitiveCount = 1;
99 addRangeElementsToSpec(spec);
100 test->addIteration(spec, "draw count = 1");
102 spec.primitiveCount = 5;
103 addRangeElementsToSpec(spec);
104 test->addIteration(spec, "draw count = 5");
106 spec.primitiveCount = 25;
107 addRangeElementsToSpec(spec);
108 test->addIteration(spec, "draw count = 25");
110 else if (type == TYPE_INSTANCE_COUNT)
112 spec.instanceCount = 1;
113 addRangeElementsToSpec(spec);
114 test->addIteration(spec, "instance count = 1");
116 spec.instanceCount = 4;
117 addRangeElementsToSpec(spec);
118 test->addIteration(spec, "instance count = 4");
120 spec.instanceCount = 11;
121 addRangeElementsToSpec(spec);
122 test->addIteration(spec, "instance count = 11");
128 static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method)
130 spec.apiType = glu::ApiType::es(3,1);
131 spec.primitive = gls::DrawTestSpec::PRIMITIVE_TRIANGLES;
132 spec.primitiveCount = 5;
133 spec.drawMethod = method;
134 spec.indexType = gls::DrawTestSpec::INDEXTYPE_LAST;
135 spec.indexPointerOffset = 0;
136 spec.indexStorage = gls::DrawTestSpec::STORAGE_LAST;
140 spec.instanceCount = 1;
141 spec.indirectOffset = 0;
143 spec.attribs.resize(2);
145 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
146 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
147 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
148 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
149 spec.attribs[0].componentCount = 4;
150 spec.attribs[0].offset = 0;
151 spec.attribs[0].stride = 0;
152 spec.attribs[0].normalize = false;
153 spec.attribs[0].instanceDivisor = 0;
154 spec.attribs[0].useDefaultAttribute = false;
156 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
157 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
158 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
159 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
160 spec.attribs[1].componentCount = 2;
161 spec.attribs[1].offset = 0;
162 spec.attribs[1].stride = 0;
163 spec.attribs[1].normalize = false;
164 spec.attribs[1].instanceDivisor = 0;
165 spec.attribs[1].useDefaultAttribute = false;
167 addRangeElementsToSpec(spec);
170 class VertexIDCase : public TestCase
173 VertexIDCase (Context& context, gls::DrawTestSpec::DrawMethod drawMethod);
174 ~VertexIDCase (void);
178 IterateResult iterate (void);
180 void draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex);
181 void verifyImage (const tcu::Surface& image);
184 const glw::Functions& m_gl;
185 glu::ShaderProgram* m_program;
186 GLuint m_coordinatesBuffer;
187 GLuint m_elementsBuffer;
189 gls::DrawTestSpec::DrawMethod m_method;
199 MAX_VERTICES = 2*3 //!< 2 triangles, totals 6 vertices
203 VertexIDCase::VertexIDCase (Context& context, gls::DrawTestSpec::DrawMethod drawMethod)
204 : TestCase (context, "vertex_id", "gl_VertexID Test")
205 , m_gl (m_context.getRenderContext().getFunctions())
206 , m_program (DE_NULL)
207 , m_coordinatesBuffer (0)
208 , m_elementsBuffer (0)
210 , m_method (drawMethod)
214 VertexIDCase::~VertexIDCase (void)
216 VertexIDCase::deinit();
219 void VertexIDCase::init (void)
221 if (m_method == deqp::gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX ||
222 m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX ||
223 m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX)
225 TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)), "This test requires a 3.2 context or higher context version.");
228 m_testCtx.getLog() << TestLog::Message
229 << "gl_VertexID should be the index of the vertex that is being passed to the shader. i.e. indices[i] + basevertex"
230 << TestLog::EndMessage;
232 DE_ASSERT(!m_program);
233 m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(
235 "in highp vec4 a_position;\n"
236 "out mediump vec4 v_color;\n"
237 "uniform highp vec4 u_colors[8];\n"
240 " gl_Position = a_position;\n"
241 " v_color = u_colors[gl_VertexID];\n"
245 "in mediump vec4 v_color;\n"
246 "layout(location = 0) out mediump vec4 o_color;\n"
249 " o_color = v_color;\n"
252 m_testCtx.getLog() << *m_program;
254 if (!m_program->isOk())
258 TCU_FAIL("Failed to compile shader program");
261 GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
263 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
264 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_elementsBuffer));
267 void VertexIDCase::deinit (void)
272 if (m_elementsBuffer)
274 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_elementsBuffer));
275 m_elementsBuffer = 0;
278 if (m_coordinatesBuffer)
280 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
281 m_coordinatesBuffer = 0;
285 void VertexIDCase::draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex)
289 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX:
290 GLU_CHECK_GLW_CALL(m_gl, drawElementsBaseVertex(mode, count, type, indices, baseVertex));
293 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX:
295 GLint maxElementsVertices = 0;
296 GLU_CHECK_GLW_CALL(m_gl, getIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementsVertices));
297 GLU_CHECK_GLW_CALL(m_gl, drawRangeElementsBaseVertex(mode, 0, maxElementsVertices, count, type, indices, baseVertex));
301 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX:
302 GLU_CHECK_GLW_CALL(m_gl, drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex));
306 DE_FATAL("Draw method not supported");
310 void VertexIDCase::verifyImage (const tcu::Surface& image)
312 tcu::TestLog& log = m_testCtx.getLog();
315 const int colorThreshold = 0; // expect perfect match
316 tcu::Surface error (image.getWidth(), image.getHeight());
318 for (int y = 0; y < image.getHeight(); y++)
319 for (int x = 0; x < image.getWidth(); x++)
321 const tcu::RGBA pixel = image.getPixel(x, y);
324 // Ignore pixels not drawn with basevertex
325 if ((x < image.getWidth()* 1/4) || (x > image.getWidth() * 3/4)
326 || (y < image.getHeight() * 1/4) || (y > image.getHeight() * 3/4))
329 // Any pixel with !(B ~= 255) is faulty
330 if (de::abs(pixel.getBlue() - 255) > colorThreshold)
333 error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
334 isOk = isOk && pixelOk;
339 log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
340 log << TestLog::ImageSet("Verification result", "Result of rendering")
341 << TestLog::Image("Result", "Result", image)
342 << TestLog::Image("Error Mask", "Error mask", error)
343 << TestLog::EndImageSet;
347 log << TestLog::ImageSet("Verification result", "Result of rendering")
348 << TestLog::Image("Result", "Result", image)
349 << TestLog::EndImageSet;
353 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
355 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
358 VertexIDCase::IterateResult VertexIDCase::iterate (void)
360 const GLuint drawCount = 6;
361 const GLuint baseVertex = 4;
362 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
363 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_colors[0]");
365 tcu::Surface surface(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
367 const GLfloat coords[] =
369 // full viewport quad
375 // half viewport quad centred
382 const GLushort indices[] =
387 const GLfloat colors[] =
389 0.0f, 0.0f, 0.0f, 1.0f,
390 0.5f, 1.0f, 0.5f, 1.0f,
391 0.0f, 0.5f, 1.0f, 1.0f,
392 0.0f, 1.0f, 0.0f, 1.0f,
394 0.0f, 0.0f, 1.0f, 1.0f, // blue
395 0.0f, 0.0f, 1.0f, 1.0f, // blue
396 0.0f, 0.0f, 1.0f, 1.0f, // blue
397 0.0f, 0.0f, 1.0f, 1.0f, // blue
400 GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT));
401 GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 1.0f, 1.0f, 1.0f)); // white
402 GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
404 GLU_CHECK_GLW_CALL(m_gl, uniform4fv(colorLocation, DE_LENGTH_OF_ARRAY(colors), &colors[0]));
406 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
407 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
408 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
409 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
413 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter0", "Indices in client-side array");
414 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, (GLvoid*)indices, baseVertex);
419 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter1", "Indices in element array buffer");
420 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsBuffer));
421 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW));
422 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, DE_NULL, baseVertex);
425 glu::readPixels(m_context.getRenderContext(), 0, 0, surface.getAccess());
426 verifyImage(surface);
430 return (m_iterNdx < 2) ? CONTINUE : STOP;
433 class BuiltInVariableGroup : public TestCaseGroup
436 BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
437 ~BuiltInVariableGroup (void);
442 gls::DrawTestSpec::DrawMethod m_method;
445 BuiltInVariableGroup::BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
446 : TestCaseGroup (context, name, descr)
447 , m_method (drawMethod)
451 BuiltInVariableGroup::~BuiltInVariableGroup (void)
455 void BuiltInVariableGroup::init (void)
457 addChild(new VertexIDCase(m_context, m_method));
460 class IndexGroup : public TestCaseGroup
463 IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
469 gls::DrawTestSpec::DrawMethod m_method;
472 IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
473 : TestCaseGroup (context, name, descr)
474 , m_method (drawMethod)
478 IndexGroup::~IndexGroup (void)
482 void IndexGroup::init (void)
486 gls::DrawTestSpec::IndexType type;
490 const IndexTest tests[] =
492 { gls::DrawTestSpec::INDEXTYPE_BYTE, { 0, 1, -1 } },
493 { gls::DrawTestSpec::INDEXTYPE_SHORT, { 0, 2, -1 } },
494 { gls::DrawTestSpec::INDEXTYPE_INT, { 0, 4, -1 } },
497 gls::DrawTestSpec spec;
498 genBasicSpec(spec, m_method);
500 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
502 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
504 const IndexTest& indexTest = tests[testNdx];
506 const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
507 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
508 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
510 spec.indexType = indexTest.type;
512 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
514 const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
515 spec.indexPointerOffset = indexTest.offsets[iterationNdx];
516 test->addIteration(spec, iterationDesc.c_str());
523 class BaseVertexGroup : public TestCaseGroup
526 BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
527 ~BaseVertexGroup (void);
532 gls::DrawTestSpec::DrawMethod m_method;
535 BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
536 : TestCaseGroup (context, name, descr)
537 , m_method (drawMethod)
541 BaseVertexGroup::~BaseVertexGroup (void)
545 void BaseVertexGroup::init (void)
550 gls::DrawTestSpec::IndexType type;
554 const IndexTest tests[] =
556 { true, gls::DrawTestSpec::INDEXTYPE_BYTE, { 1, 2 } },
557 { true, gls::DrawTestSpec::INDEXTYPE_SHORT, { 1, 2 } },
558 { true, gls::DrawTestSpec::INDEXTYPE_INT, { 1, 2 } },
559 { false, gls::DrawTestSpec::INDEXTYPE_BYTE, { -1, -2 } },
560 { false, gls::DrawTestSpec::INDEXTYPE_SHORT, { -1, -2 } },
561 { false, gls::DrawTestSpec::INDEXTYPE_INT, { -1, -2 } },
564 gls::DrawTestSpec spec;
565 genBasicSpec(spec, m_method);
567 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
569 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
571 const IndexTest& indexTest = tests[testNdx];
573 const std::string name = std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
574 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
575 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
577 spec.indexType = indexTest.type;
579 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
581 const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
582 spec.baseVertex = indexTest.baseVertex[iterationNdx];
583 // spec.indexMin + spec.baseVertex can not be a negative value
584 if (spec.indexMin + spec.baseVertex < 0)
586 spec.indexMax -= (spec.indexMin + spec.baseVertex);
587 spec.indexMin -= (spec.indexMin + spec.baseVertex);
589 test->addIteration(spec, iterationDesc.c_str());
596 class AttributeGroup : public TestCaseGroup
599 AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage);
600 ~AttributeGroup (void);
605 gls::DrawTestSpec::DrawMethod m_method;
606 gls::DrawTestSpec::Primitive m_primitive;
607 gls::DrawTestSpec::IndexType m_indexType;
608 gls::DrawTestSpec::Storage m_indexStorage;
611 AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage)
612 : TestCaseGroup (context, name, descr)
613 , m_method (drawMethod)
614 , m_primitive (primitive)
615 , m_indexType (indexType)
616 , m_indexStorage (indexStorage)
620 AttributeGroup::~AttributeGroup (void)
624 void AttributeGroup::init (void)
628 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
629 gls::DrawTestSpec spec;
631 spec.apiType = glu::ApiType::es(3,1);
632 spec.primitive = m_primitive;
633 spec.primitiveCount = 5;
634 spec.drawMethod = m_method;
635 spec.indexType = m_indexType;
636 spec.indexPointerOffset = 0;
637 spec.indexStorage = m_indexStorage;
641 spec.instanceCount = 1;
642 spec.indirectOffset = 0;
644 spec.attribs.resize(1);
646 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
647 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
648 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
649 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
650 spec.attribs[0].componentCount = 2;
651 spec.attribs[0].offset = 0;
652 spec.attribs[0].stride = 0;
653 spec.attribs[0].normalize = false;
654 spec.attribs[0].instanceDivisor = 0;
655 spec.attribs[0].useDefaultAttribute = false;
657 addTestIterations(test, spec, TYPE_DRAW_COUNT);
659 this->addChild(test);
662 // Multiple attribute
664 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
665 gls::DrawTestSpec spec;
667 spec.apiType = glu::ApiType::es(3,1);
668 spec.primitive = m_primitive;
669 spec.primitiveCount = 5;
670 spec.drawMethod = m_method;
671 spec.indexType = m_indexType;
672 spec.indexPointerOffset = 0;
673 spec.indexStorage = m_indexStorage;
677 spec.instanceCount = 1;
678 spec.indirectOffset = 0;
680 spec.attribs.resize(2);
682 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
683 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
684 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
685 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
686 spec.attribs[0].componentCount = 4;
687 spec.attribs[0].offset = 0;
688 spec.attribs[0].stride = 0;
689 spec.attribs[0].normalize = false;
690 spec.attribs[0].instanceDivisor = 0;
691 spec.attribs[0].useDefaultAttribute = false;
693 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
694 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
695 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
696 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
697 spec.attribs[1].componentCount = 2;
698 spec.attribs[1].offset = 0;
699 spec.attribs[1].stride = 0;
700 spec.attribs[1].normalize = false;
701 spec.attribs[1].instanceDivisor = 0;
702 spec.attribs[1].useDefaultAttribute = false;
704 addTestIterations(test, spec, TYPE_DRAW_COUNT);
706 this->addChild(test);
709 // Multiple attribute, second one divided
711 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
712 gls::DrawTestSpec spec;
714 spec.apiType = glu::ApiType::es(3,1);
715 spec.primitive = m_primitive;
716 spec.primitiveCount = 5;
717 spec.drawMethod = m_method;
718 spec.indexType = m_indexType;
719 spec.indexPointerOffset = 0;
720 spec.indexStorage = m_indexStorage;
724 spec.instanceCount = 1;
725 spec.indirectOffset = 0;
727 spec.attribs.resize(3);
729 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
730 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
731 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
732 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
733 spec.attribs[0].componentCount = 4;
734 spec.attribs[0].offset = 0;
735 spec.attribs[0].stride = 0;
736 spec.attribs[0].normalize = false;
737 spec.attribs[0].instanceDivisor = 0;
738 spec.attribs[0].useDefaultAttribute = false;
740 // Add another position component so the instances wont be drawn on each other
741 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
742 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
743 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
744 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
745 spec.attribs[1].componentCount = 2;
746 spec.attribs[1].offset = 0;
747 spec.attribs[1].stride = 0;
748 spec.attribs[1].normalize = false;
749 spec.attribs[1].instanceDivisor = 1;
750 spec.attribs[1].useDefaultAttribute = false;
751 spec.attribs[1].additionalPositionAttribute = true;
754 spec.attribs[2].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
755 spec.attribs[2].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
756 spec.attribs[2].storage = gls::DrawTestSpec::STORAGE_BUFFER;
757 spec.attribs[2].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
758 spec.attribs[2].componentCount = 3;
759 spec.attribs[2].offset = 0;
760 spec.attribs[2].stride = 0;
761 spec.attribs[2].normalize = false;
762 spec.attribs[2].instanceDivisor = 1;
763 spec.attribs[2].useDefaultAttribute = false;
765 addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
767 this->addChild(test);
770 // Multiple attribute, second one default
772 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
773 gls::DrawTestSpec spec;
775 spec.apiType = glu::ApiType::es(3,1);
776 spec.primitive = m_primitive;
777 spec.primitiveCount = 5;
778 spec.drawMethod = m_method;
779 spec.indexType = m_indexType;
780 spec.indexPointerOffset = 0;
781 spec.indexStorage = m_indexStorage;
785 spec.instanceCount = 1;
786 spec.indirectOffset = 0;
788 spec.attribs.resize(2);
790 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
791 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
792 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
793 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
794 spec.attribs[0].componentCount = 2;
795 spec.attribs[0].offset = 0;
796 spec.attribs[0].stride = 0;
797 spec.attribs[0].normalize = false;
798 spec.attribs[0].instanceDivisor = 0;
799 spec.attribs[0].useDefaultAttribute = false;
803 gls::DrawTestSpec::InputType input;
804 gls::DrawTestSpec::OutputType output;
808 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4 },
809 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2 },
810 { gls::DrawTestSpec::INPUTTYPE_INT, gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
811 { gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
814 for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
816 const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
818 spec.attribs[1].inputType = iopairs[ioNdx].input;
819 spec.attribs[1].outputType = iopairs[ioNdx].output;
820 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
821 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
822 spec.attribs[1].componentCount = iopairs[ioNdx].componentCount;
823 spec.attribs[1].offset = 0;
824 spec.attribs[1].stride = 0;
825 spec.attribs[1].normalize = false;
826 spec.attribs[1].instanceDivisor = 0;
827 spec.attribs[1].useDefaultAttribute = true;
829 test->addIteration(spec, desc.c_str());
832 this->addChild(test);
836 class MethodGroup : public TestCaseGroup
839 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
845 gls::DrawTestSpec::DrawMethod m_method;
848 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
849 : TestCaseGroup (context, name, descr)
850 , m_method (drawMethod)
854 MethodGroup::~MethodGroup (void)
858 void MethodGroup::init (void)
860 const bool indexed = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
861 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
862 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX);
864 const gls::DrawTestSpec::Primitive primitive[] =
866 gls::DrawTestSpec::PRIMITIVE_POINTS,
867 gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
868 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
869 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
870 gls::DrawTestSpec::PRIMITIVE_LINES,
871 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
872 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
878 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
879 this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
880 this->addChild(new BuiltInVariableGroup(m_context, "builtin_variable", "Built in shader variable tests", m_method));
883 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
885 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
886 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
888 this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
894 DrawElementsBaseVertexTests::DrawElementsBaseVertexTests (Context& context)
895 : TestCaseGroup(context, "draw_base_vertex", "Base vertex extension drawing tests")
899 DrawElementsBaseVertexTests::~DrawElementsBaseVertexTests (void)
903 void DrawElementsBaseVertexTests::init (void)
905 const gls::DrawTestSpec::DrawMethod basicMethods[] =
907 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
908 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
909 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
912 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
914 const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
915 const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
917 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));