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 m_testCtx.getLog() << TestLog::Message
222 << "gl_VertexID should be the index of the vertex that is being passed to the shader. i.e. indices[i] + basevertex"
223 << TestLog::EndMessage;
225 DE_ASSERT(!m_program);
226 m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(
228 "in highp vec4 a_position;\n"
229 "out mediump vec4 v_color;\n"
230 "uniform highp vec4 u_colors[8];\n"
233 " gl_Position = a_position;\n"
234 " v_color = u_colors[gl_VertexID];\n"
238 "in mediump vec4 v_color;\n"
239 "layout(location = 0) out mediump vec4 o_color;\n"
242 " o_color = v_color;\n"
245 m_testCtx.getLog() << *m_program;
247 if (!m_program->isOk())
251 TCU_FAIL("Failed to compile shader program");
254 GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
256 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
257 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_elementsBuffer));
260 void VertexIDCase::deinit (void)
265 if (m_elementsBuffer)
267 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_elementsBuffer));
268 m_elementsBuffer = 0;
271 if (m_coordinatesBuffer)
273 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
274 m_coordinatesBuffer = 0;
278 void VertexIDCase::draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex)
282 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX:
283 GLU_CHECK_GLW_CALL(m_gl, drawElementsBaseVertex(mode, count, type, indices, baseVertex));
286 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX:
288 GLint maxElementsVertices = 0;
289 GLU_CHECK_GLW_CALL(m_gl, getIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementsVertices));
290 GLU_CHECK_GLW_CALL(m_gl, drawRangeElementsBaseVertex(mode, 0, maxElementsVertices, count, type, indices, baseVertex));
294 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX:
295 GLU_CHECK_GLW_CALL(m_gl, drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex));
299 DE_FATAL("Draw method not supported");
303 void VertexIDCase::verifyImage (const tcu::Surface& image)
305 tcu::TestLog& log = m_testCtx.getLog();
308 const int colorThreshold = 0; // expect perfect match
309 tcu::Surface error (image.getWidth(), image.getHeight());
311 for (int y = 0; y < image.getHeight(); y++)
312 for (int x = 0; x < image.getWidth(); x++)
314 const tcu::RGBA pixel = image.getPixel(x, y);
317 // Ignore pixels not drawn with basevertex
318 if ((x < image.getWidth()* 1/4) || (x > image.getWidth() * 3/4)
319 || (y < image.getHeight() * 1/4) || (y > image.getHeight() * 3/4))
322 // Any pixel with !(B ~= 255) is faulty
323 if (de::abs(pixel.getBlue() - 255) > colorThreshold)
326 error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
327 isOk = isOk && pixelOk;
332 log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
333 log << TestLog::ImageSet("Verification result", "Result of rendering")
334 << TestLog::Image("Result", "Result", image)
335 << TestLog::Image("Error Mask", "Error mask", error)
336 << TestLog::EndImageSet;
340 log << TestLog::ImageSet("Verification result", "Result of rendering")
341 << TestLog::Image("Result", "Result", image)
342 << TestLog::EndImageSet;
346 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
348 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
351 VertexIDCase::IterateResult VertexIDCase::iterate (void)
353 const GLuint drawCount = 6;
354 const GLuint baseVertex = 4;
355 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
356 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_colors[0]");
358 tcu::Surface surface(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
360 const GLfloat coords[] =
362 // full viewport quad
368 // half viewport quad centred
375 const GLushort indices[] =
380 const GLfloat colors[] =
382 0.0f, 0.0f, 0.0f, 1.0f,
383 0.5f, 1.0f, 0.5f, 1.0f,
384 0.0f, 0.5f, 1.0f, 1.0f,
385 0.0f, 1.0f, 0.0f, 1.0f,
387 0.0f, 0.0f, 1.0f, 1.0f, // blue
388 0.0f, 0.0f, 1.0f, 1.0f, // blue
389 0.0f, 0.0f, 1.0f, 1.0f, // blue
390 0.0f, 0.0f, 1.0f, 1.0f, // blue
393 GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT));
394 GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 1.0f, 1.0f, 1.0f)); // white
395 GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
397 GLU_CHECK_GLW_CALL(m_gl, uniform4fv(colorLocation, DE_LENGTH_OF_ARRAY(colors), &colors[0]));
399 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
400 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
401 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
402 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
406 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter0", "Indices in client-side array");
407 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, (GLvoid*)indices, baseVertex);
412 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter1", "Indices in element array buffer");
413 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsBuffer));
414 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW));
415 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, DE_NULL, baseVertex);
418 glu::readPixels(m_context.getRenderContext(), 0, 0, surface.getAccess());
419 verifyImage(surface);
423 return (m_iterNdx < 2) ? CONTINUE : STOP;
426 class BuiltInVariableGroup : public TestCaseGroup
429 BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
430 ~BuiltInVariableGroup (void);
435 gls::DrawTestSpec::DrawMethod m_method;
438 BuiltInVariableGroup::BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
439 : TestCaseGroup (context, name, descr)
440 , m_method (drawMethod)
444 BuiltInVariableGroup::~BuiltInVariableGroup (void)
448 void BuiltInVariableGroup::init (void)
450 addChild(new VertexIDCase(m_context, m_method));
453 class IndexGroup : public TestCaseGroup
456 IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
462 gls::DrawTestSpec::DrawMethod m_method;
465 IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
466 : TestCaseGroup (context, name, descr)
467 , m_method (drawMethod)
471 IndexGroup::~IndexGroup (void)
475 void IndexGroup::init (void)
479 gls::DrawTestSpec::IndexType type;
483 const IndexTest tests[] =
485 { gls::DrawTestSpec::INDEXTYPE_BYTE, { 0, 1, -1 } },
486 { gls::DrawTestSpec::INDEXTYPE_SHORT, { 0, 2, -1 } },
487 { gls::DrawTestSpec::INDEXTYPE_INT, { 0, 4, -1 } },
490 gls::DrawTestSpec spec;
491 genBasicSpec(spec, m_method);
493 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
495 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
497 const IndexTest& indexTest = tests[testNdx];
499 const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
500 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
501 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
503 spec.indexType = indexTest.type;
505 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
507 const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
508 spec.indexPointerOffset = indexTest.offsets[iterationNdx];
509 test->addIteration(spec, iterationDesc.c_str());
516 class BaseVertexGroup : public TestCaseGroup
519 BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
520 ~BaseVertexGroup (void);
525 gls::DrawTestSpec::DrawMethod m_method;
528 BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
529 : TestCaseGroup (context, name, descr)
530 , m_method (drawMethod)
534 BaseVertexGroup::~BaseVertexGroup (void)
538 void BaseVertexGroup::init (void)
543 gls::DrawTestSpec::IndexType type;
547 const IndexTest tests[] =
549 { true, gls::DrawTestSpec::INDEXTYPE_BYTE, { 1, 2 } },
550 { true, gls::DrawTestSpec::INDEXTYPE_SHORT, { 1, 2 } },
551 { true, gls::DrawTestSpec::INDEXTYPE_INT, { 1, 2 } },
552 { false, gls::DrawTestSpec::INDEXTYPE_BYTE, { -1, -2 } },
553 { false, gls::DrawTestSpec::INDEXTYPE_SHORT, { -1, -2 } },
554 { false, gls::DrawTestSpec::INDEXTYPE_INT, { -1, -2 } },
557 gls::DrawTestSpec spec;
558 genBasicSpec(spec, m_method);
560 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
562 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
564 const IndexTest& indexTest = tests[testNdx];
566 const std::string name = std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
567 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
568 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
570 spec.indexType = indexTest.type;
572 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
574 const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
575 spec.baseVertex = indexTest.baseVertex[iterationNdx];
576 test->addIteration(spec, iterationDesc.c_str());
583 class AttributeGroup : public TestCaseGroup
586 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);
587 ~AttributeGroup (void);
592 gls::DrawTestSpec::DrawMethod m_method;
593 gls::DrawTestSpec::Primitive m_primitive;
594 gls::DrawTestSpec::IndexType m_indexType;
595 gls::DrawTestSpec::Storage m_indexStorage;
598 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)
599 : TestCaseGroup (context, name, descr)
600 , m_method (drawMethod)
601 , m_primitive (primitive)
602 , m_indexType (indexType)
603 , m_indexStorage (indexStorage)
607 AttributeGroup::~AttributeGroup (void)
611 void AttributeGroup::init (void)
615 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
616 gls::DrawTestSpec spec;
618 spec.apiType = glu::ApiType::es(3,1);
619 spec.primitive = m_primitive;
620 spec.primitiveCount = 5;
621 spec.drawMethod = m_method;
622 spec.indexType = m_indexType;
623 spec.indexPointerOffset = 0;
624 spec.indexStorage = m_indexStorage;
628 spec.instanceCount = 1;
629 spec.indirectOffset = 0;
631 spec.attribs.resize(1);
633 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
634 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
635 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
636 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
637 spec.attribs[0].componentCount = 2;
638 spec.attribs[0].offset = 0;
639 spec.attribs[0].stride = 0;
640 spec.attribs[0].normalize = false;
641 spec.attribs[0].instanceDivisor = 0;
642 spec.attribs[0].useDefaultAttribute = false;
644 addTestIterations(test, spec, TYPE_DRAW_COUNT);
646 this->addChild(test);
649 // Multiple attribute
651 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
652 gls::DrawTestSpec spec;
654 spec.apiType = glu::ApiType::es(3,1);
655 spec.primitive = m_primitive;
656 spec.primitiveCount = 5;
657 spec.drawMethod = m_method;
658 spec.indexType = m_indexType;
659 spec.indexPointerOffset = 0;
660 spec.indexStorage = m_indexStorage;
664 spec.instanceCount = 1;
665 spec.indirectOffset = 0;
667 spec.attribs.resize(2);
669 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
670 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
671 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
672 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
673 spec.attribs[0].componentCount = 4;
674 spec.attribs[0].offset = 0;
675 spec.attribs[0].stride = 0;
676 spec.attribs[0].normalize = false;
677 spec.attribs[0].instanceDivisor = 0;
678 spec.attribs[0].useDefaultAttribute = false;
680 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
681 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
682 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
683 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
684 spec.attribs[1].componentCount = 2;
685 spec.attribs[1].offset = 0;
686 spec.attribs[1].stride = 0;
687 spec.attribs[1].normalize = false;
688 spec.attribs[1].instanceDivisor = 0;
689 spec.attribs[1].useDefaultAttribute = false;
691 addTestIterations(test, spec, TYPE_DRAW_COUNT);
693 this->addChild(test);
696 // Multiple attribute, second one divided
698 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
699 gls::DrawTestSpec spec;
701 spec.apiType = glu::ApiType::es(3,1);
702 spec.primitive = m_primitive;
703 spec.primitiveCount = 5;
704 spec.drawMethod = m_method;
705 spec.indexType = m_indexType;
706 spec.indexPointerOffset = 0;
707 spec.indexStorage = m_indexStorage;
711 spec.instanceCount = 1;
712 spec.indirectOffset = 0;
714 spec.attribs.resize(3);
716 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
717 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
718 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
719 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
720 spec.attribs[0].componentCount = 4;
721 spec.attribs[0].offset = 0;
722 spec.attribs[0].stride = 0;
723 spec.attribs[0].normalize = false;
724 spec.attribs[0].instanceDivisor = 0;
725 spec.attribs[0].useDefaultAttribute = false;
727 // Add another position component so the instances wont be drawn on each other
728 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
729 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
730 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
731 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
732 spec.attribs[1].componentCount = 2;
733 spec.attribs[1].offset = 0;
734 spec.attribs[1].stride = 0;
735 spec.attribs[1].normalize = false;
736 spec.attribs[1].instanceDivisor = 1;
737 spec.attribs[1].useDefaultAttribute = false;
738 spec.attribs[1].additionalPositionAttribute = true;
741 spec.attribs[2].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
742 spec.attribs[2].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
743 spec.attribs[2].storage = gls::DrawTestSpec::STORAGE_BUFFER;
744 spec.attribs[2].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
745 spec.attribs[2].componentCount = 3;
746 spec.attribs[2].offset = 0;
747 spec.attribs[2].stride = 0;
748 spec.attribs[2].normalize = false;
749 spec.attribs[2].instanceDivisor = 1;
750 spec.attribs[2].useDefaultAttribute = false;
752 addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
754 this->addChild(test);
757 // Multiple attribute, second one default
759 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
760 gls::DrawTestSpec spec;
762 spec.apiType = glu::ApiType::es(3,1);
763 spec.primitive = m_primitive;
764 spec.primitiveCount = 5;
765 spec.drawMethod = m_method;
766 spec.indexType = m_indexType;
767 spec.indexPointerOffset = 0;
768 spec.indexStorage = m_indexStorage;
772 spec.instanceCount = 1;
773 spec.indirectOffset = 0;
775 spec.attribs.resize(2);
777 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
778 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
779 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
780 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
781 spec.attribs[0].componentCount = 2;
782 spec.attribs[0].offset = 0;
783 spec.attribs[0].stride = 0;
784 spec.attribs[0].normalize = false;
785 spec.attribs[0].instanceDivisor = 0;
786 spec.attribs[0].useDefaultAttribute = false;
790 gls::DrawTestSpec::InputType input;
791 gls::DrawTestSpec::OutputType output;
795 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4 },
796 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2 },
797 { gls::DrawTestSpec::INPUTTYPE_INT, gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
798 { gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
801 for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
803 const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
805 spec.attribs[1].inputType = iopairs[ioNdx].input;
806 spec.attribs[1].outputType = iopairs[ioNdx].output;
807 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
808 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
809 spec.attribs[1].componentCount = iopairs[ioNdx].componentCount;
810 spec.attribs[1].offset = 0;
811 spec.attribs[1].stride = 0;
812 spec.attribs[1].normalize = false;
813 spec.attribs[1].instanceDivisor = 0;
814 spec.attribs[1].useDefaultAttribute = true;
816 test->addIteration(spec, desc.c_str());
819 this->addChild(test);
823 class MethodGroup : public TestCaseGroup
826 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
832 gls::DrawTestSpec::DrawMethod m_method;
835 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
836 : TestCaseGroup (context, name, descr)
837 , m_method (drawMethod)
841 MethodGroup::~MethodGroup (void)
845 void MethodGroup::init (void)
847 const bool indexed = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
848 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
849 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX);
851 const gls::DrawTestSpec::Primitive primitive[] =
853 gls::DrawTestSpec::PRIMITIVE_POINTS,
854 gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
855 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
856 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
857 gls::DrawTestSpec::PRIMITIVE_LINES,
858 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
859 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
865 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
866 this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
867 this->addChild(new BuiltInVariableGroup(m_context, "builtin_variable", "Built in shader variable tests", m_method));
870 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
872 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
873 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
875 this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
881 DrawElementsBaseVertexTests::DrawElementsBaseVertexTests (Context& context)
882 : TestCaseGroup(context, "draw_base_vertex", "Base vertex extension drawing tests")
886 DrawElementsBaseVertexTests::~DrawElementsBaseVertexTests (void)
890 void DrawElementsBaseVertexTests::init (void)
892 const gls::DrawTestSpec::DrawMethod basicMethods[] =
894 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
895 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
896 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
899 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
901 const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
902 const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
904 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));