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 const bool supportsES32 = contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
226 TCU_CHECK_AND_THROW(NotSupportedError, supportsES32 || m_context.getContextInfo().isExtensionSupported("GL_EXT_draw_elements_base_vertex"), "GL_EXT_draw_elements_base_vertex is not supported.");
229 m_testCtx.getLog() << TestLog::Message
230 << "gl_VertexID should be the index of the vertex that is being passed to the shader. i.e. indices[i] + basevertex"
231 << TestLog::EndMessage;
233 DE_ASSERT(!m_program);
234 m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(
236 "in highp vec4 a_position;\n"
237 "out mediump vec4 v_color;\n"
238 "uniform highp vec4 u_colors[8];\n"
241 " gl_Position = a_position;\n"
242 " v_color = u_colors[gl_VertexID];\n"
246 "in mediump vec4 v_color;\n"
247 "layout(location = 0) out mediump vec4 o_color;\n"
250 " o_color = v_color;\n"
253 m_testCtx.getLog() << *m_program;
255 if (!m_program->isOk())
259 TCU_FAIL("Failed to compile shader program");
262 GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
264 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
265 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_elementsBuffer));
268 void VertexIDCase::deinit (void)
273 if (m_elementsBuffer)
275 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_elementsBuffer));
276 m_elementsBuffer = 0;
279 if (m_coordinatesBuffer)
281 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
282 m_coordinatesBuffer = 0;
286 void VertexIDCase::draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex)
290 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX:
291 GLU_CHECK_GLW_CALL(m_gl, drawElementsBaseVertex(mode, count, type, indices, baseVertex));
294 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX:
296 GLint maxElementsVertices = 0;
297 GLU_CHECK_GLW_CALL(m_gl, getIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementsVertices));
298 GLU_CHECK_GLW_CALL(m_gl, drawRangeElementsBaseVertex(mode, 0, maxElementsVertices, count, type, indices, baseVertex));
302 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX:
303 GLU_CHECK_GLW_CALL(m_gl, drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex));
307 DE_FATAL("Draw method not supported");
311 void VertexIDCase::verifyImage (const tcu::Surface& image)
313 tcu::TestLog& log = m_testCtx.getLog();
316 const int colorThreshold = 0; // expect perfect match
317 tcu::Surface error (image.getWidth(), image.getHeight());
319 for (int y = 0; y < image.getHeight(); y++)
320 for (int x = 0; x < image.getWidth(); x++)
322 const tcu::RGBA pixel = image.getPixel(x, y);
325 // Ignore pixels not drawn with basevertex
326 if ((x < image.getWidth()* 1/4) || (x > image.getWidth() * 3/4)
327 || (y < image.getHeight() * 1/4) || (y > image.getHeight() * 3/4))
330 // Any pixel with !(B ~= 255) is faulty
331 if (de::abs(pixel.getBlue() - 255) > colorThreshold)
334 error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255)));
335 isOk = isOk && pixelOk;
340 log << TestLog::Message << "Image verification failed." << TestLog::EndMessage;
341 log << TestLog::ImageSet("Verification result", "Result of rendering")
342 << TestLog::Image("Result", "Result", image)
343 << TestLog::Image("Error Mask", "Error mask", error)
344 << TestLog::EndImageSet;
348 log << TestLog::ImageSet("Verification result", "Result of rendering")
349 << TestLog::Image("Result", "Result", image)
350 << TestLog::EndImageSet;
354 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
356 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid");
359 VertexIDCase::IterateResult VertexIDCase::iterate (void)
361 const GLuint drawCount = 6;
362 const GLuint baseVertex = 4;
363 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position");
364 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_colors[0]");
366 tcu::Surface surface(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
368 const GLfloat coords[] =
370 // full viewport quad
376 // half viewport quad centred
383 const GLushort indices[] =
388 const GLfloat colors[] =
390 0.0f, 0.0f, 0.0f, 1.0f,
391 0.5f, 1.0f, 0.5f, 1.0f,
392 0.0f, 0.5f, 1.0f, 1.0f,
393 0.0f, 1.0f, 0.0f, 1.0f,
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
398 0.0f, 0.0f, 1.0f, 1.0f, // blue
401 GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT));
402 GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 1.0f, 1.0f, 1.0f)); // white
403 GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
405 GLU_CHECK_GLW_CALL(m_gl, uniform4fv(colorLocation, DE_LENGTH_OF_ARRAY(colors), &colors[0]));
407 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
408 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
409 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
410 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
414 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter0", "Indices in client-side array");
415 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, (GLvoid*)indices, baseVertex);
420 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter1", "Indices in element array buffer");
421 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsBuffer));
422 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW));
423 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, DE_NULL, baseVertex);
426 glu::readPixels(m_context.getRenderContext(), 0, 0, surface.getAccess());
427 verifyImage(surface);
431 return (m_iterNdx < 2) ? CONTINUE : STOP;
434 class BuiltInVariableGroup : public TestCaseGroup
437 BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
438 ~BuiltInVariableGroup (void);
443 gls::DrawTestSpec::DrawMethod m_method;
446 BuiltInVariableGroup::BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
447 : TestCaseGroup (context, name, descr)
448 , m_method (drawMethod)
452 BuiltInVariableGroup::~BuiltInVariableGroup (void)
456 void BuiltInVariableGroup::init (void)
458 addChild(new VertexIDCase(m_context, m_method));
461 class IndexGroup : public TestCaseGroup
464 IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
470 gls::DrawTestSpec::DrawMethod m_method;
473 IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
474 : TestCaseGroup (context, name, descr)
475 , m_method (drawMethod)
479 IndexGroup::~IndexGroup (void)
483 void IndexGroup::init (void)
487 gls::DrawTestSpec::IndexType type;
491 const IndexTest tests[] =
493 { gls::DrawTestSpec::INDEXTYPE_BYTE, { 0, 1, -1 } },
494 { gls::DrawTestSpec::INDEXTYPE_SHORT, { 0, 2, -1 } },
495 { gls::DrawTestSpec::INDEXTYPE_INT, { 0, 4, -1 } },
498 gls::DrawTestSpec spec;
499 genBasicSpec(spec, m_method);
501 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
503 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
505 const IndexTest& indexTest = tests[testNdx];
507 const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
508 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
509 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
511 spec.indexType = indexTest.type;
513 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx)
515 const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type));
516 spec.indexPointerOffset = indexTest.offsets[iterationNdx];
517 test->addIteration(spec, iterationDesc.c_str());
524 class BaseVertexGroup : public TestCaseGroup
527 BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
528 ~BaseVertexGroup (void);
533 gls::DrawTestSpec::DrawMethod m_method;
536 BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
537 : TestCaseGroup (context, name, descr)
538 , m_method (drawMethod)
542 BaseVertexGroup::~BaseVertexGroup (void)
546 void BaseVertexGroup::init (void)
551 gls::DrawTestSpec::IndexType type;
555 const IndexTest tests[] =
557 { true, gls::DrawTestSpec::INDEXTYPE_BYTE, { 1, 2 } },
558 { true, gls::DrawTestSpec::INDEXTYPE_SHORT, { 1, 2 } },
559 { true, gls::DrawTestSpec::INDEXTYPE_INT, { 1, 2 } },
560 { false, gls::DrawTestSpec::INDEXTYPE_BYTE, { -1, -2 } },
561 { false, gls::DrawTestSpec::INDEXTYPE_SHORT, { -1, -2 } },
562 { false, gls::DrawTestSpec::INDEXTYPE_INT, { -1, -2 } },
565 gls::DrawTestSpec spec;
566 genBasicSpec(spec, m_method);
568 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER;
570 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
572 const IndexTest& indexTest = tests[testNdx];
574 const std::string name = std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
575 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type);
576 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str());
578 spec.indexType = indexTest.type;
580 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx)
582 const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]);
583 spec.baseVertex = indexTest.baseVertex[iterationNdx];
584 // spec.indexMin + spec.baseVertex can not be a negative value
585 if (spec.indexMin + spec.baseVertex < 0)
587 spec.indexMax -= (spec.indexMin + spec.baseVertex);
588 spec.indexMin -= (spec.indexMin + spec.baseVertex);
590 test->addIteration(spec, iterationDesc.c_str());
597 class AttributeGroup : public TestCaseGroup
600 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);
601 ~AttributeGroup (void);
606 gls::DrawTestSpec::DrawMethod m_method;
607 gls::DrawTestSpec::Primitive m_primitive;
608 gls::DrawTestSpec::IndexType m_indexType;
609 gls::DrawTestSpec::Storage m_indexStorage;
612 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)
613 : TestCaseGroup (context, name, descr)
614 , m_method (drawMethod)
615 , m_primitive (primitive)
616 , m_indexType (indexType)
617 , m_indexStorage (indexStorage)
621 AttributeGroup::~AttributeGroup (void)
625 void AttributeGroup::init (void)
629 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array.");
630 gls::DrawTestSpec spec;
632 spec.apiType = glu::ApiType::es(3,1);
633 spec.primitive = m_primitive;
634 spec.primitiveCount = 5;
635 spec.drawMethod = m_method;
636 spec.indexType = m_indexType;
637 spec.indexPointerOffset = 0;
638 spec.indexStorage = m_indexStorage;
642 spec.instanceCount = 1;
643 spec.indirectOffset = 0;
645 spec.attribs.resize(1);
647 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
648 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
649 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
650 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
651 spec.attribs[0].componentCount = 2;
652 spec.attribs[0].offset = 0;
653 spec.attribs[0].stride = 0;
654 spec.attribs[0].normalize = false;
655 spec.attribs[0].instanceDivisor = 0;
656 spec.attribs[0].useDefaultAttribute = false;
658 addTestIterations(test, spec, TYPE_DRAW_COUNT);
660 this->addChild(test);
663 // Multiple attribute
665 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays.");
666 gls::DrawTestSpec spec;
668 spec.apiType = glu::ApiType::es(3,1);
669 spec.primitive = m_primitive;
670 spec.primitiveCount = 5;
671 spec.drawMethod = m_method;
672 spec.indexType = m_indexType;
673 spec.indexPointerOffset = 0;
674 spec.indexStorage = m_indexStorage;
678 spec.instanceCount = 1;
679 spec.indirectOffset = 0;
681 spec.attribs.resize(2);
683 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
684 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
685 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
686 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
687 spec.attribs[0].componentCount = 4;
688 spec.attribs[0].offset = 0;
689 spec.attribs[0].stride = 0;
690 spec.attribs[0].normalize = false;
691 spec.attribs[0].instanceDivisor = 0;
692 spec.attribs[0].useDefaultAttribute = false;
694 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
695 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
696 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
697 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
698 spec.attribs[1].componentCount = 2;
699 spec.attribs[1].offset = 0;
700 spec.attribs[1].stride = 0;
701 spec.attribs[1].normalize = false;
702 spec.attribs[1].instanceDivisor = 0;
703 spec.attribs[1].useDefaultAttribute = false;
705 addTestIterations(test, spec, TYPE_DRAW_COUNT);
707 this->addChild(test);
710 // Multiple attribute, second one divided
712 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array.");
713 gls::DrawTestSpec spec;
715 spec.apiType = glu::ApiType::es(3,1);
716 spec.primitive = m_primitive;
717 spec.primitiveCount = 5;
718 spec.drawMethod = m_method;
719 spec.indexType = m_indexType;
720 spec.indexPointerOffset = 0;
721 spec.indexStorage = m_indexStorage;
725 spec.instanceCount = 1;
726 spec.indirectOffset = 0;
728 spec.attribs.resize(3);
730 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
731 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
732 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
733 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
734 spec.attribs[0].componentCount = 4;
735 spec.attribs[0].offset = 0;
736 spec.attribs[0].stride = 0;
737 spec.attribs[0].normalize = false;
738 spec.attribs[0].instanceDivisor = 0;
739 spec.attribs[0].useDefaultAttribute = false;
741 // Add another position component so the instances wont be drawn on each other
742 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
743 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
744 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
745 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
746 spec.attribs[1].componentCount = 2;
747 spec.attribs[1].offset = 0;
748 spec.attribs[1].stride = 0;
749 spec.attribs[1].normalize = false;
750 spec.attribs[1].instanceDivisor = 1;
751 spec.attribs[1].useDefaultAttribute = false;
752 spec.attribs[1].additionalPositionAttribute = true;
755 spec.attribs[2].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
756 spec.attribs[2].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
757 spec.attribs[2].storage = gls::DrawTestSpec::STORAGE_BUFFER;
758 spec.attribs[2].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
759 spec.attribs[2].componentCount = 3;
760 spec.attribs[2].offset = 0;
761 spec.attribs[2].stride = 0;
762 spec.attribs[2].normalize = false;
763 spec.attribs[2].instanceDivisor = 1;
764 spec.attribs[2].useDefaultAttribute = false;
766 addTestIterations(test, spec, TYPE_INSTANCE_COUNT);
768 this->addChild(test);
771 // Multiple attribute, second one default
773 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*.");
774 gls::DrawTestSpec spec;
776 spec.apiType = glu::ApiType::es(3,1);
777 spec.primitive = m_primitive;
778 spec.primitiveCount = 5;
779 spec.drawMethod = m_method;
780 spec.indexType = m_indexType;
781 spec.indexPointerOffset = 0;
782 spec.indexStorage = m_indexStorage;
786 spec.instanceCount = 1;
787 spec.indirectOffset = 0;
789 spec.attribs.resize(2);
791 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT;
792 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2;
793 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER;
794 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
795 spec.attribs[0].componentCount = 2;
796 spec.attribs[0].offset = 0;
797 spec.attribs[0].stride = 0;
798 spec.attribs[0].normalize = false;
799 spec.attribs[0].instanceDivisor = 0;
800 spec.attribs[0].useDefaultAttribute = false;
804 gls::DrawTestSpec::InputType input;
805 gls::DrawTestSpec::OutputType output;
809 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4 },
810 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2 },
811 { gls::DrawTestSpec::INPUTTYPE_INT, gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 },
812 { gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 },
815 for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx)
817 const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output);
819 spec.attribs[1].inputType = iopairs[ioNdx].input;
820 spec.attribs[1].outputType = iopairs[ioNdx].output;
821 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER;
822 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW;
823 spec.attribs[1].componentCount = iopairs[ioNdx].componentCount;
824 spec.attribs[1].offset = 0;
825 spec.attribs[1].stride = 0;
826 spec.attribs[1].normalize = false;
827 spec.attribs[1].instanceDivisor = 0;
828 spec.attribs[1].useDefaultAttribute = true;
830 test->addIteration(spec, desc.c_str());
833 this->addChild(test);
837 class MethodGroup : public TestCaseGroup
840 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod);
846 gls::DrawTestSpec::DrawMethod m_method;
849 MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod)
850 : TestCaseGroup (context, name, descr)
851 , m_method (drawMethod)
855 MethodGroup::~MethodGroup (void)
859 void MethodGroup::init (void)
861 const bool indexed = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX)
862 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX)
863 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX);
865 const gls::DrawTestSpec::Primitive primitive[] =
867 gls::DrawTestSpec::PRIMITIVE_POINTS,
868 gls::DrawTestSpec::PRIMITIVE_TRIANGLES,
869 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN,
870 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP,
871 gls::DrawTestSpec::PRIMITIVE_LINES,
872 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP,
873 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP
879 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method));
880 this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method));
881 this->addChild(new BuiltInVariableGroup(m_context, "builtin_variable", "Built in shader variable tests", m_method));
884 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx)
886 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
887 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]);
889 this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER));
895 DrawElementsBaseVertexTests::DrawElementsBaseVertexTests (Context& context)
896 : TestCaseGroup(context, "draw_base_vertex", "Base vertex extension drawing tests")
900 DrawElementsBaseVertexTests::~DrawElementsBaseVertexTests (void)
904 void DrawElementsBaseVertexTests::init (void)
906 const gls::DrawTestSpec::DrawMethod basicMethods[] =
908 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX,
909 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX,
910 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX,
913 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx)
915 const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
916 const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]);
918 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx]));