1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
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.
22 */ /*-------------------------------------------------------------------*/
26 * \file gl4cIndirectParametersTests.cpp
27 * \brief Conformance tests for the GL_ARB_indirect_parameters functionality.
28 */ /*-------------------------------------------------------------------*/
30 #include "gl4cIndirectParametersTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluDrawUtil.hpp"
34 #include "gluShaderProgram.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuRenderTarget.hpp"
38 #include "tcuTestLog.hpp"
46 static const char* c_vertShader = "#version 430\n"
52 " gl_Position = vec4(vertex, 1);\n"
55 static const char* c_fragShader = "#version 430\n"
57 "out vec4 fragColor;\n"
61 " fragColor = vec4(1, 1, 1, 0.5);\n"
66 * @param context Rendering context
68 ParameterBufferOperationsCase::ParameterBufferOperationsCase(deqp::Context& context)
69 : TestCase(context, "ParameterBufferOperations",
70 "Verifies if operations on new buffer object PARAMETER_BUFFER_ARB works as expected.")
72 /* Left blank intentionally */
75 /** Stub init method */
76 void ParameterBufferOperationsCase::init()
80 /** Executes test iteration.
82 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
84 tcu::TestNode::IterateResult ParameterBufferOperationsCase::iterate()
86 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
88 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
92 const Functions& gl = m_context.getRenderContext().getFunctions();
96 GLint data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
97 GLint subData[] = { 10, 11, 12, 13, 14 };
98 GLint expData[] = { 0, 1, 10, 11, 12, 13, 14, 7, 8, 9 };
102 // Test buffer generating and binding
103 gl.genBuffers(1, ¶mBuffer);
104 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
106 gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, paramBuffer);
107 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
110 gl.getIntegerv(GL_PARAMETER_BUFFER_BINDING_ARB, ¶mBinding);
111 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
113 if ((GLuint)paramBinding != paramBuffer)
116 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer binding mismatch" << tcu::TestLog::EndMessage;
120 // Test filling buffer with data
121 gl.bufferData(GL_PARAMETER_BUFFER_ARB, 10 * sizeof(GLint), data, GL_DYNAMIC_DRAW);
122 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
124 gl.bufferSubData(GL_PARAMETER_BUFFER_ARB, 2 * sizeof(GLint), 5 * sizeof(GLint), subData);
125 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
127 // Test buffer mapping
128 GLvoid* buffer = gl.mapBuffer(GL_PARAMETER_BUFFER_ARB, GL_READ_ONLY);
129 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer");
131 if (memcmp(buffer, expData, 10 * sizeof(GLint)) != 0)
134 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer data mismatch" << tcu::TestLog::EndMessage;
138 GLvoid* bufferPointer;
139 gl.getBufferPointerv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_MAP_POINTER, &bufferPointer);
140 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferPointerv");
142 if (buffer != bufferPointer)
145 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer pointer mismatch" << tcu::TestLog::EndMessage;
151 gl.getBufferParameteriv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_SIZE, &bufferSize);
152 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
153 gl.getBufferParameteriv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_USAGE, &bufferUsage);
154 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
156 if (bufferSize != 10 * sizeof(GLint))
159 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size mismatch" << tcu::TestLog::EndMessage;
161 else if (bufferUsage != GL_DYNAMIC_DRAW)
164 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer usage mismatch" << tcu::TestLog::EndMessage;
169 gl.unmapBuffer(GL_PARAMETER_BUFFER_ARB);
170 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
172 // Test buffer ranged mapping
174 gl.mapBufferRange(GL_PARAMETER_BUFFER_ARB, 0, sizeof(GLint), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
175 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
177 // Test buffer flushing
178 GLint* bufferInt = (GLint*)buffer;
181 gl.flushMappedBufferRange(GL_PARAMETER_BUFFER_ARB, 0, sizeof(GLint));
182 GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange");
184 gl.unmapBuffer(GL_PARAMETER_BUFFER_ARB);
185 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
187 // Test buffers data copying
189 gl.genBuffers(1, &arrayBuffer);
190 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
192 gl.bindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
193 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
195 gl.bufferData(GL_ARRAY_BUFFER, 10 * sizeof(GLint), data, GL_DYNAMIC_DRAW);
196 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
198 gl.copyBufferSubData(GL_PARAMETER_BUFFER_ARB, GL_ARRAY_BUFFER, 0, 0, sizeof(GLint));
199 GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData");
201 gl.mapBufferRange(GL_ARRAY_BUFFER, 0, 1, GL_MAP_READ_BIT);
202 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
204 bufferInt = (GLint*)buffer;
205 if (bufferInt[0] != 100)
208 m_testCtx.getLog() << tcu::TestLog::Message << "Buffer copy operation failed" << tcu::TestLog::EndMessage;
211 gl.unmapBuffer(GL_ARRAY_BUFFER);
212 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
214 // Release array buffer
215 gl.deleteBuffers(1, &arrayBuffer);
216 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
219 // Release parameter buffer
220 gl.deleteBuffers(1, ¶mBuffer);
221 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
224 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
226 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
233 * @param context Rendering context
235 VertexArrayIndirectDrawingBaseCase::VertexArrayIndirectDrawingBaseCase(deqp::Context& context, const char* name,
236 const char* description)
237 : TestCase(context, name, description)
239 /* Left blank intentionally */
242 /** Executes test iteration.
244 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
246 tcu::TestNode::IterateResult VertexArrayIndirectDrawingBaseCase::iterate()
248 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
250 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
254 if (draw() && verify())
255 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
257 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
262 /** This method verifies if drawn quads are as expected.
264 * @return Returns true if quads are drawn properly, false otherwise.
266 bool VertexArrayIndirectDrawingBaseCase::verify()
268 const Functions& gl = m_context.getRenderContext().getFunctions();
269 const tcu::RenderTarget& rt = m_context.getRenderContext().getRenderTarget();
271 const int width = rt.getWidth();
272 const int height = rt.getHeight();
274 std::vector<GLubyte> pixels;
275 pixels.resize(width * height);
277 gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
278 gl.readPixels(0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, pixels.data());
279 gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
282 for (int y = 2; y < height - 2; ++y)
284 for (int x = 2; x < width / 2 - 2; ++x)
286 GLubyte value = pixels[x + y * width];
287 if (value < 190 || value > 194)
289 m_testCtx.getLog() << tcu::TestLog::Message << "First quad verification failed. "
290 << "Wrong value read from framebuffer at " << x << "/" << y << " value: " << value
291 << ", expected: <190-194>" << tcu::TestLog::EndMessage;
298 for (int y = 2; y < height - 2; ++y)
300 for (int x = width / 2 + 2; x < width - 2; ++x)
302 GLubyte value = pixels[x + y * width];
303 if (value < 126 || value > 130)
305 m_testCtx.getLog() << tcu::TestLog::Message << "Second quad verification failed. "
306 << "Wrong value read from framebuffer at " << x << "/" << y << " value: " << value
307 << ", expected: <126-130>" << tcu::TestLog::EndMessage;
313 return verifyErrors();
318 * @param context Rendering context
320 MultiDrawArraysIndirectCountCase::MultiDrawArraysIndirectCountCase(deqp::Context& context)
321 : VertexArrayIndirectDrawingBaseCase(context, "MultiDrawArraysIndirectCount",
322 "Test verifies if MultiDrawArraysIndirectCountARB function works as expected.")
325 , m_drawIndirectBuffer(0)
326 , m_parameterBuffer(0)
328 /* Left blank intentionally */
331 /** Stub init method */
332 void MultiDrawArraysIndirectCountCase::init()
334 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
337 const Functions& gl = m_context.getRenderContext().getFunctions();
339 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
340 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f };
342 const DrawArraysIndirectCommand indirect[] = {
343 { 4, 2, 0, 0 }, //4 vertices, 2 instanceCount, 0 first, 0 baseInstance
344 { 4, 1, 2, 0 } //4 vertices, 1 instanceCount, 2 first, 0 baseInstance
347 const GLushort parameters[] = { 2, 1 };
349 // Generate vertex array object
350 gl.genVertexArrays(1, &m_vao);
351 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
353 gl.bindVertexArray(m_vao);
354 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
356 // Setup vertex array buffer
357 gl.genBuffers(1, &m_arrayBuffer);
358 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
360 gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
361 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
363 gl.bufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
364 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
366 // Setup indirect command buffer
367 gl.genBuffers(1, &m_drawIndirectBuffer);
368 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
370 gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
371 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
373 gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 2 * sizeof(DrawArraysIndirectCommand), indirect, GL_STATIC_DRAW);
374 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
376 // Setup parameter buffer
377 gl.genBuffers(1, &m_parameterBuffer);
378 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
380 gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, m_parameterBuffer);
381 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
383 gl.bufferData(GL_PARAMETER_BUFFER_ARB, 100 * sizeof(GLushort), parameters, GL_STATIC_DRAW);
384 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
387 /** Stub deinit method */
388 void MultiDrawArraysIndirectCountCase::deinit()
390 const Functions& gl = m_context.getRenderContext().getFunctions();
393 gl.deleteVertexArrays(1, &m_vao);
395 gl.deleteBuffers(1, &m_arrayBuffer);
396 if (m_drawIndirectBuffer)
397 gl.deleteBuffers(1, &m_drawIndirectBuffer);
398 if (m_parameterBuffer)
399 gl.deleteBuffers(1, &m_parameterBuffer);
402 /** Drawing quads method using drawArrays.
404 bool MultiDrawArraysIndirectCountCase::draw()
406 const Functions& gl = m_context.getRenderContext().getFunctions();
408 ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
409 ShaderProgram program(gl, sources);
413 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
414 << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
415 << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
416 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
420 gl.useProgram(program.getProgram());
421 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
423 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
424 gl.clear(GL_COLOR_BUFFER_BIT);
427 gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
429 gl.enableVertexAttribArray(0);
430 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
431 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
432 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
434 gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 0, 2, 0);
435 GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawArraysIndirectCountARB");
437 gl.disableVertexAttribArray(0);
438 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
440 gl.disable(GL_BLEND);
445 /** Verify MultiDrawArrayIndirectCountARB errors
447 bool MultiDrawArraysIndirectCountCase::verifyErrors()
449 const Functions& gl = m_context.getRenderContext().getFunctions();
455 // INVALID_VALUE - drawcount offset not multiple of 4
456 gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 2, 1, 0);
457 errorCode = gl.getError();
458 if (errorCode != GL_INVALID_VALUE)
460 m_testCtx.getLog() << tcu::TestLog::Message
461 << "MultiDrawArraysIndirectCount error verifying failed (1). Expected code: "
462 << GL_INVALID_VALUE << ", current code: " << errorCode << tcu::TestLog::EndMessage;
466 // INVALID_OPERATION - maxdrawcount greater then parameter buffer size
467 gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 0, 4, 0);
468 errorCode = gl.getError();
469 if (errorCode != GL_INVALID_OPERATION)
471 m_testCtx.getLog() << tcu::TestLog::Message
472 << "MultiDrawArraysIndirectCount error verifying failed (2). Expected code: "
473 << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
477 gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, 0);
478 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
480 // INVALID_OPERATION - GL_PARAMETER_BUFFER_ARB not bound
481 gl.multiDrawArraysIndirectCount(GL_TRIANGLE_STRIP, 0, 0, 2, 0);
482 errorCode = gl.getError();
483 if (errorCode != GL_INVALID_OPERATION)
485 m_testCtx.getLog() << tcu::TestLog::Message
486 << "MultiDrawArraysIndirectCount error verifying failed (3). Expected code: "
487 << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
496 * @param context Rendering context
498 MultiDrawElementsIndirectCountCase::MultiDrawElementsIndirectCountCase(deqp::Context& context)
499 : VertexArrayIndirectDrawingBaseCase(
500 context, "MultiDrawElementsIndirectCount",
501 "Test verifies if MultiDrawElementsIndirectCountARB function works as expected.")
504 , m_drawIndirectBuffer(0)
505 , m_parameterBuffer(0)
507 /* Left blank intentionally */
510 /** Stub init method */
511 void MultiDrawElementsIndirectCountCase::init()
513 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
516 const Functions& gl = m_context.getRenderContext().getFunctions();
518 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
519 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f };
521 const GLushort elements[] = { 0, 1, 2, 3, 4, 5 };
523 const DrawElementsIndirectCommand indirect[] = {
524 { 4, 2, 0, 0, 0 }, //4 indices, 2 instanceCount, 0 firstIndex, 0 baseVertex, 0 baseInstance
525 { 4, 1, 2, 0, 0 } //4 indices, 1 instanceCount, 2 firstIndex, 0 baseVertex, 0 baseInstance
528 const GLushort parameters[] = { 2, 1 };
530 // Generate vertex array object
531 gl.genVertexArrays(1, &m_vao);
532 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
534 gl.bindVertexArray(m_vao);
535 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
537 // Setup vertex array buffer
538 gl.genBuffers(1, &m_arrayBuffer);
539 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
541 gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
542 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
544 gl.bufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
545 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
547 // Setup element array buffer
548 gl.genBuffers(1, &m_elementBuffer);
549 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
551 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
552 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
554 gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLushort), elements, GL_STATIC_DRAW);
555 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
557 // Setup indirect command buffer
558 gl.genBuffers(1, &m_drawIndirectBuffer);
559 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
561 gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
562 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
564 gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 3 * sizeof(DrawElementsIndirectCommand), indirect, GL_STATIC_DRAW);
565 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
567 // Setup parameters Re: buffer
568 gl.genBuffers(1, &m_parameterBuffer);
569 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
571 gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, m_parameterBuffer);
572 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
574 gl.bufferData(GL_PARAMETER_BUFFER_ARB, 2 * sizeof(GLushort), parameters, GL_STATIC_DRAW);
575 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
578 /** Stub deinit method */
579 void MultiDrawElementsIndirectCountCase::deinit()
581 const Functions& gl = m_context.getRenderContext().getFunctions();
584 gl.deleteVertexArrays(1, &m_vao);
586 gl.deleteBuffers(1, &m_arrayBuffer);
588 gl.deleteBuffers(1, &m_elementBuffer);
589 if (m_drawIndirectBuffer)
590 gl.deleteBuffers(1, &m_drawIndirectBuffer);
591 if (m_parameterBuffer)
592 gl.deleteBuffers(1, &m_parameterBuffer);
595 /** Drawing quads method using drawArrays.
597 bool MultiDrawElementsIndirectCountCase::draw()
599 const Functions& gl = m_context.getRenderContext().getFunctions();
601 ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
602 ShaderProgram program(gl, sources);
606 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
607 << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
608 << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
609 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
613 gl.useProgram(program.getProgram());
614 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
616 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
617 gl.clear(GL_COLOR_BUFFER_BIT);
620 gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
622 gl.enableVertexAttribArray(0);
623 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
624 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
625 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
627 gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, 0, 0, 2, 0);
628 GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawElementsIndirectCountARB");
630 gl.disableVertexAttribArray(0);
631 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
633 gl.disable(GL_BLEND);
638 /** Verify MultiDrawElementsIndirectCountARB errors
640 bool MultiDrawElementsIndirectCountCase::verifyErrors()
642 const Functions& gl = m_context.getRenderContext().getFunctions();
648 // INVALID_VALUE - drawcount offset not multiple of 4
649 gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 2, 1, 0);
650 errorCode = gl.getError();
651 if (errorCode != GL_INVALID_VALUE)
653 m_testCtx.getLog() << tcu::TestLog::Message
654 << "MultiDrawElementIndirectCount error verifying failed (1). Expected code: "
655 << GL_INVALID_VALUE << ", current code: " << errorCode << tcu::TestLog::EndMessage;
659 // INVALID_OPERATION - maxdrawcount greater then parameter buffer size
660 gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 0, 4, 0);
661 errorCode = gl.getError();
662 if (errorCode != GL_INVALID_OPERATION)
664 m_testCtx.getLog() << tcu::TestLog::Message
665 << "MultiDrawElementIndirectCount error verifying failed (2). Expected code: "
666 << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
670 gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, 0);
671 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
673 // INVALID_OPERATION - GL_PARAMETER_BUFFER_ARB not bound
674 gl.multiDrawElementsIndirectCount(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 0, 3, 0);
675 errorCode = gl.getError();
676 if (errorCode != GL_INVALID_OPERATION)
678 m_testCtx.getLog() << tcu::TestLog::Message
679 << "MultiDrawElementIndirectCount error verifying failed (3). Expected code: "
680 << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
689 * @param context Rendering context.
691 IndirectParametersTests::IndirectParametersTests(deqp::Context& context)
692 : TestCaseGroup(context, "indirect_parameters_tests",
693 "Verify conformance of CTS_ARB_indirect_parameters implementation")
697 /** Initializes the test group contents. */
698 void IndirectParametersTests::init()
700 addChild(new ParameterBufferOperationsCase(m_context));
701 addChild(new MultiDrawArraysIndirectCountCase(m_context));
702 addChild(new MultiDrawElementsIndirectCountCase(m_context));
705 } /* gl4cts namespace */