Add CTS_ARB_indirect_parameters implementation
This is CTS_ARB_indirect_parameters tests implementation
Affects:
GL45-CTS.indirect_parameters_tests.*
Components: OpenGL, Framework
VK-GL-CTS issue: 194
Change-Id: Ibddff6daf485a9d673cf1b09554c01b8b83958e1
diff --git a/external/openglcts/modules/gl/CMakeLists.txt b/external/openglcts/modules/gl/CMakeLists.txt
index ca93752..a606bc2 100644
--- a/external/openglcts/modules/gl/CMakeLists.txt
+++ b/external/openglcts/modules/gl/CMakeLists.txt
@@ -112,6 +112,8 @@
gl4cParallelShaderCompileTests.hpp
gl4cPostDepthCoverageTests.cpp
gl4cPostDepthCoverageTests.hpp
+ gl4cIndirectParametersTests.cpp
+ gl4cIndirectParametersTests.hpp
)
set(GLCTS_GL_LIBS
diff --git a/external/openglcts/modules/gl/gl4cIndirectParametersTests.cpp b/external/openglcts/modules/gl/gl4cIndirectParametersTests.cpp
new file mode 100644
index 0000000..dfb39bf
--- /dev/null
+++ b/external/openglcts/modules/gl/gl4cIndirectParametersTests.cpp
@@ -0,0 +1,703 @@
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file
+ * \brief
+ */ /*-------------------------------------------------------------------*/
+
+/**
+ */ /*!
+ * \file gl4cIndirectParametersTests.cpp
+ * \brief Conformance tests for the GL_ARB_indirect_parameters functionality.
+ */ /*-------------------------------------------------------------------*/
+
+#include "gl4cIndirectParametersTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluDefs.hpp"
+#include "gluDrawUtil.hpp"
+#include "gluShaderProgram.hpp"
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuTestLog.hpp"
+
+using namespace glw;
+using namespace glu;
+
+namespace gl4cts
+{
+
+static const char* c_vertShader = "#version 430\n"
+ "\n"
+ "in vec3 vertex;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex, 1);\n"
+ "}\n";
+
+static const char* c_fragShader = "#version 430\n"
+ "\n"
+ "out vec4 fragColor;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(1, 1, 1, 0.5);\n"
+ "}\n";
+
+/** Constructor.
+ *
+ * @param context Rendering context
+ */
+ParameterBufferOperationsCase::ParameterBufferOperationsCase(deqp::Context& context)
+ : TestCase(context, "ParameterBufferOperations",
+ "Verifies if operations on new buffer object PARAMETER_BUFFER_ARB works as expected.")
+{
+ /* Left blank intentionally */
+}
+
+/** Stub init method */
+void ParameterBufferOperationsCase::init()
+{
+}
+
+/** Executes test iteration.
+ *
+ * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+ */
+tcu::TestNode::IterateResult ParameterBufferOperationsCase::iterate()
+{
+ if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
+ {
+ m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
+ return STOP;
+ }
+
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ GLuint paramBuffer;
+
+ GLint data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ GLint subData[] = { 10, 11, 12, 13, 14 };
+ GLint expData[] = { 0, 1, 10, 11, 12, 13, 14, 7, 8, 9 };
+
+ bool result = true;
+
+ // Test buffer generating and binding
+ gl.genBuffers(1, ¶mBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, paramBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ GLint paramBinding;
+ gl.getIntegerv(GL_PARAMETER_BUFFER_BINDING_ARB, ¶mBinding);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv");
+
+ if ((GLuint)paramBinding != paramBuffer)
+ {
+ result = false;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Buffer binding mismatch" << tcu::TestLog::EndMessage;
+ }
+ else
+ {
+ // Test filling buffer with data
+ gl.bufferData(GL_PARAMETER_BUFFER_ARB, 10 * sizeof(GLint), data, GL_DYNAMIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ gl.bufferSubData(GL_PARAMETER_BUFFER_ARB, 2 * sizeof(GLint), 5 * sizeof(GLint), subData);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Test buffer mapping
+ GLvoid* buffer = gl.mapBuffer(GL_PARAMETER_BUFFER_ARB, GL_READ_ONLY);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer");
+
+ if (memcmp(buffer, expData, 10 * sizeof(GLint)) != 0)
+ {
+ result = false;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Buffer data mismatch" << tcu::TestLog::EndMessage;
+ }
+ else
+ {
+ GLvoid* bufferPointer;
+ gl.getBufferPointerv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_MAP_POINTER, &bufferPointer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferPointerv");
+
+ if (buffer != bufferPointer)
+ {
+ result = false;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Buffer pointer mismatch" << tcu::TestLog::EndMessage;
+ }
+ else
+ {
+ GLint bufferSize;
+ GLint bufferUsage;
+ gl.getBufferParameteriv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_SIZE, &bufferSize);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
+ gl.getBufferParameteriv(GL_PARAMETER_BUFFER_ARB, GL_BUFFER_USAGE, &bufferUsage);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv");
+
+ if (bufferSize != 10 * sizeof(GLint))
+ {
+ result = false;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size mismatch" << tcu::TestLog::EndMessage;
+ }
+ else if (bufferUsage != GL_DYNAMIC_DRAW)
+ {
+ result = false;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Buffer usage mismatch" << tcu::TestLog::EndMessage;
+ }
+ }
+ }
+
+ gl.unmapBuffer(GL_PARAMETER_BUFFER_ARB);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
+
+ // Test buffer ranged mapping
+ buffer =
+ gl.mapBufferRange(GL_PARAMETER_BUFFER_ARB, 0, sizeof(GLint), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
+
+ // Test buffer flushing
+ GLint* bufferInt = (GLint*)buffer;
+
+ bufferInt[0] = 100;
+ gl.flushMappedBufferRange(GL_PARAMETER_BUFFER_ARB, 0, sizeof(GLint));
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange");
+
+ gl.unmapBuffer(GL_PARAMETER_BUFFER_ARB);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
+
+ // Test buffers data copying
+ GLuint arrayBuffer;
+ gl.genBuffers(1, &arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_ARRAY_BUFFER, 10 * sizeof(GLint), data, GL_DYNAMIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ gl.copyBufferSubData(GL_PARAMETER_BUFFER_ARB, GL_ARRAY_BUFFER, 0, 0, sizeof(GLint));
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyBufferSubData");
+
+ gl.mapBufferRange(GL_ARRAY_BUFFER, 0, 1, GL_MAP_READ_BIT);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange");
+
+ bufferInt = (GLint*)buffer;
+ if (bufferInt[0] != 100)
+ {
+ result = false;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Buffer copy operation failed" << tcu::TestLog::EndMessage;
+ }
+
+ gl.unmapBuffer(GL_ARRAY_BUFFER);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer");
+
+ // Release array buffer
+ gl.deleteBuffers(1, &arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
+ }
+
+ // Release parameter buffer
+ gl.deleteBuffers(1, ¶mBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
+
+ if (result)
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ else
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+ return STOP;
+}
+
+/** Constructor.
+ *
+ * @param context Rendering context
+ */
+VertexArrayIndirectDrawingBaseCase::VertexArrayIndirectDrawingBaseCase(deqp::Context& context, const char* name,
+ const char* description)
+ : TestCase(context, name, description)
+{
+ /* Left blank intentionally */
+}
+
+/** Executes test iteration.
+ *
+ * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+ */
+tcu::TestNode::IterateResult VertexArrayIndirectDrawingBaseCase::iterate()
+{
+ if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
+ {
+ m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
+ return STOP;
+ }
+
+ if (draw() && verify())
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ else
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+ return STOP;
+}
+
+/** This method verifies if drawn quads are as expected.
+ *
+ * @return Returns true if quads are drawn properly, false otherwise.
+ */
+bool VertexArrayIndirectDrawingBaseCase::verify()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+ const tcu::RenderTarget& rt = m_context.getRenderContext().getRenderTarget();
+
+ const int width = rt.getWidth();
+ const int height = rt.getHeight();
+
+ std::vector<GLubyte> pixels;
+ pixels.resize(width * height);
+
+ gl.readPixels(0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, pixels.data());
+
+ //Verify first quad
+ for (int y = 2; y < height - 2; ++y)
+ {
+ for (int x = 2; x < width / 2 - 2; ++x)
+ {
+ GLubyte value = pixels[x + y * width];
+ if (value < 190 || value > 194)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "First quad verification failed. "
+ << "Wrong value read from framebuffer at " << x << "/" << y << " value: " << value
+ << ", expected: <190-194>" << tcu::TestLog::EndMessage;
+ return false;
+ }
+ }
+ }
+
+ //Verify second quad
+ for (int y = 2; y < height - 2; ++y)
+ {
+ for (int x = width / 2 + 2; x < width - 2; ++x)
+ {
+ GLubyte value = pixels[x + y * width];
+ if (value < 126 || value > 130)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "Second quad verification failed. "
+ << "Wrong value read from framebuffer at " << x << "/" << y << " value: " << value
+ << ", expected: <126-130>" << tcu::TestLog::EndMessage;
+ return false;
+ }
+ }
+ }
+
+ return verifyErrors();
+}
+
+/** Constructor.
+ *
+ * @param context Rendering context
+ */
+MultiDrawArraysIndirectCountCase::MultiDrawArraysIndirectCountCase(deqp::Context& context)
+ : VertexArrayIndirectDrawingBaseCase(context, "MultiDrawArraysIndirectCount",
+ "Test verifies if MultiDrawArraysIndirectCountARB function works as expected.")
+ , m_vao(0)
+ , m_arrayBuffer(0)
+ , m_drawIndirectBuffer(0)
+ , m_parameterBuffer(0)
+{
+ /* Left blank intentionally */
+}
+
+/** Stub init method */
+void MultiDrawArraysIndirectCountCase::init()
+{
+ if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
+ return;
+
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f };
+
+ const DrawArraysIndirectCommand indirect[] = {
+ { 4, 2, 0, 0 }, //4 vertices, 2 instanceCount, 0 first, 0 baseInstance
+ { 4, 1, 2, 0 } //4 vertices, 1 instanceCount, 2 first, 0 baseInstance
+ };
+
+ const GLushort parameters[] = { 2, 1 };
+
+ // Generate vertex array object
+ gl.genVertexArrays(1, &m_vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
+
+ gl.bindVertexArray(m_vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
+
+ // Setup vertex array buffer
+ gl.genBuffers(1, &m_arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Setup indirect command buffer
+ gl.genBuffers(1, &m_drawIndirectBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 2 * sizeof(DrawArraysIndirectCommand), indirect, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Setup parameter buffer
+ gl.genBuffers(1, &m_parameterBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, m_parameterBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_PARAMETER_BUFFER_ARB, 100 * sizeof(GLushort), parameters, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+}
+
+/** Stub deinit method */
+void MultiDrawArraysIndirectCountCase::deinit()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ if (m_vao)
+ gl.deleteVertexArrays(1, &m_vao);
+ if (m_arrayBuffer)
+ gl.deleteBuffers(1, &m_arrayBuffer);
+ if (m_drawIndirectBuffer)
+ gl.deleteBuffers(1, &m_drawIndirectBuffer);
+ if (m_parameterBuffer)
+ gl.deleteBuffers(1, &m_parameterBuffer);
+}
+
+/** Drawing quads method using drawArrays.
+ */
+bool MultiDrawArraysIndirectCountCase::draw()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
+ ShaderProgram program(gl, sources);
+
+ if (!program.isOk())
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
+ << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
+ << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
+ << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
+ return false;
+ }
+
+ gl.useProgram(program.getProgram());
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
+
+ gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ gl.clear(GL_COLOR_BUFFER_BIT);
+
+ gl.enable(GL_BLEND);
+ gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ gl.enableVertexAttribArray(0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
+ gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
+
+ gl.multiDrawArraysIndirectCountARB(GL_TRIANGLE_STRIP, 0, 0, 2, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawArraysIndirectCountARB");
+
+ gl.disableVertexAttribArray(0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
+
+ gl.disable(GL_BLEND);
+
+ return true;
+}
+
+/** Verify MultiDrawArrayIndirectCountARB errors
+ */
+bool MultiDrawArraysIndirectCountCase::verifyErrors()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ GLint errorCode;
+
+ bool result = true;
+
+ // INVALID_VALUE - drawcount offset not multiple of 4
+ gl.multiDrawArraysIndirectCountARB(GL_TRIANGLE_STRIP, 0, 2, 1, 0);
+ errorCode = gl.getError();
+ if (errorCode != GL_INVALID_VALUE)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "MultiDrawArraysIndirectCount error verifying failed (1). Expected code: "
+ << GL_INVALID_VALUE << ", current code: " << errorCode << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ // INVALID_OPERATION - maxdrawcount greater then parameter buffer size
+ gl.multiDrawArraysIndirectCountARB(GL_TRIANGLE_STRIP, 0, 0, 4, 0);
+ errorCode = gl.getError();
+ if (errorCode != GL_INVALID_OPERATION)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "MultiDrawArraysIndirectCount error verifying failed (2). Expected code: "
+ << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ // INVALID_OPERATION - GL_PARAMETER_BUFFER_ARB not bound
+ gl.multiDrawArraysIndirectCountARB(GL_TRIANGLE_STRIP, 0, 0, 2, 0);
+ errorCode = gl.getError();
+ if (errorCode != GL_INVALID_OPERATION)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "MultiDrawArraysIndirectCount error verifying failed (3). Expected code: "
+ << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ return result;
+}
+
+/** Constructor.
+ *
+ * @param context Rendering context
+ */
+MultiDrawElementsIndirectCountCase::MultiDrawElementsIndirectCountCase(deqp::Context& context)
+ : VertexArrayIndirectDrawingBaseCase(
+ context, "MultiDrawElementsIndirectCount",
+ "Test verifies if MultiDrawElementsIndirectCountARB function works as expected.")
+ , m_vao(0)
+ , m_arrayBuffer(0)
+ , m_drawIndirectBuffer(0)
+ , m_parameterBuffer(0)
+{
+ /* Left blank intentionally */
+}
+
+/** Stub init method */
+void MultiDrawElementsIndirectCountCase::init()
+{
+ if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_indirect_parameters"))
+ return;
+
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f };
+
+ const GLushort elements[] = { 0, 1, 2, 3, 4, 5 };
+
+ const DrawElementsIndirectCommand indirect[] = {
+ { 4, 2, 0, 0, 0 }, //4 indices, 2 instanceCount, 0 firstIndex, 0 baseVertex, 0 baseInstance
+ { 4, 1, 2, 0, 0 } //4 indices, 1 instanceCount, 2 firstIndex, 0 baseVertex, 0 baseInstance
+ };
+
+ const GLushort parameters[] = { 2, 1 };
+
+ // Generate vertex array object
+ gl.genVertexArrays(1, &m_vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
+
+ gl.bindVertexArray(m_vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
+
+ // Setup vertex array buffer
+ gl.genBuffers(1, &m_arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Setup element array buffer
+ gl.genBuffers(1, &m_elementBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLushort), elements, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Setup indirect command buffer
+ gl.genBuffers(1, &m_drawIndirectBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_DRAW_INDIRECT_BUFFER, 3 * sizeof(DrawElementsIndirectCommand), indirect, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Setup parameters Re: buffer
+ gl.genBuffers(1, &m_parameterBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
+
+ gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, m_parameterBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ gl.bufferData(GL_PARAMETER_BUFFER_ARB, 2 * sizeof(GLushort), parameters, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+}
+
+/** Stub deinit method */
+void MultiDrawElementsIndirectCountCase::deinit()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ if (m_vao)
+ gl.deleteVertexArrays(1, &m_vao);
+ if (m_arrayBuffer)
+ gl.deleteBuffers(1, &m_arrayBuffer);
+ if (m_elementBuffer)
+ gl.deleteBuffers(1, &m_elementBuffer);
+ if (m_drawIndirectBuffer)
+ gl.deleteBuffers(1, &m_drawIndirectBuffer);
+ if (m_parameterBuffer)
+ gl.deleteBuffers(1, &m_parameterBuffer);
+}
+
+/** Drawing quads method using drawArrays.
+ */
+bool MultiDrawElementsIndirectCountCase::draw()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ ProgramSources sources = makeVtxFragSources(c_vertShader, c_fragShader);
+ ShaderProgram program(gl, sources);
+
+ if (!program.isOk())
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
+ << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
+ << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
+ << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
+ return false;
+ }
+
+ gl.useProgram(program.getProgram());
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
+
+ gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ gl.clear(GL_COLOR_BUFFER_BIT);
+
+ gl.enable(GL_BLEND);
+ gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ gl.enableVertexAttribArray(0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
+ gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
+
+ gl.multiDrawElementsIndirectCountARB(GL_TRIANGLE_STRIP, GL_UNSIGNED_SHORT, 0, 0, 2, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glMultiDrawElementsIndirectCountARB");
+
+ gl.disableVertexAttribArray(0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
+
+ gl.disable(GL_BLEND);
+
+ return true;
+}
+
+/** Verify MultiDrawElementsIndirectCountARB errors
+ */
+bool MultiDrawElementsIndirectCountCase::verifyErrors()
+{
+ const Functions& gl = m_context.getRenderContext().getFunctions();
+
+ GLint errorCode;
+
+ bool result = true;
+
+ // INVALID_VALUE - drawcount offset not multiple of 4
+ gl.multiDrawElementsIndirectCountARB(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 2, 1, 0);
+ errorCode = gl.getError();
+ if (errorCode != GL_INVALID_VALUE)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "MultiDrawElementIndirectCount error verifying failed (1). Expected code: "
+ << GL_INVALID_VALUE << ", current code: " << errorCode << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ // INVALID_OPERATION - maxdrawcount greater then parameter buffer size
+ gl.multiDrawElementsIndirectCountARB(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 0, 4, 0);
+ errorCode = gl.getError();
+ if (errorCode != GL_INVALID_OPERATION)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "MultiDrawElementIndirectCount error verifying failed (2). Expected code: "
+ << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ gl.bindBuffer(GL_PARAMETER_BUFFER_ARB, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
+
+ // INVALID_OPERATION - GL_PARAMETER_BUFFER_ARB not bound
+ gl.multiDrawElementsIndirectCountARB(GL_TRIANGLE_STRIP, GL_UNSIGNED_BYTE, 0, 0, 3, 0);
+ errorCode = gl.getError();
+ if (errorCode != GL_INVALID_OPERATION)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "MultiDrawElementIndirectCount error verifying failed (3). Expected code: "
+ << GL_INVALID_OPERATION << ", current code: " << errorCode << tcu::TestLog::EndMessage;
+ result = false;
+ }
+
+ return result;
+}
+
+/** Constructor.
+ *
+ * @param context Rendering context.
+ */
+IndirectParametersTests::IndirectParametersTests(deqp::Context& context)
+ : TestCaseGroup(context, "indirect_parameters_tests",
+ "Verify conformance of CTS_ARB_indirect_parameters implementation")
+{
+}
+
+/** Initializes the test group contents. */
+void IndirectParametersTests::init()
+{
+ addChild(new ParameterBufferOperationsCase(m_context));
+ addChild(new MultiDrawArraysIndirectCountCase(m_context));
+ addChild(new MultiDrawElementsIndirectCountCase(m_context));
+}
+
+} /* gl4cts namespace */
diff --git a/external/openglcts/modules/gl/gl4cIndirectParametersTests.hpp b/external/openglcts/modules/gl/gl4cIndirectParametersTests.hpp
new file mode 100644
index 0000000..09728db
--- /dev/null
+++ b/external/openglcts/modules/gl/gl4cIndirectParametersTests.hpp
@@ -0,0 +1,157 @@
+#ifndef _GL4CINDIRECTPARAMETERSTESTS_HPP
+#define _GL4CINDIRECTPARAMETERSTESTS_HPP
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2017 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file
+ * \brief
+ */ /*-------------------------------------------------------------------*/
+
+/**
+ */ /*!
+ * \file gl4cIndirectParametersTests.hpp
+ * \brief Conformance tests for the GL_ARB_indirect_parameters functionality.
+ */ /*-------------------------------------------------------------------*/
+
+#include "glcTestCase.hpp"
+#include "glwDefs.hpp"
+#include "tcuDefs.hpp"
+
+using namespace glw;
+using namespace glu;
+
+namespace gl4cts
+{
+
+typedef struct
+{
+ GLuint count;
+ GLuint instanceCount;
+ GLuint first;
+ GLuint baseInstance;
+} DrawArraysIndirectCommand;
+
+typedef struct
+{
+ GLuint count;
+ GLuint instanceCount;
+ GLuint firstIndex;
+ GLuint baseVertex;
+ GLuint baseInstance;
+} DrawElementsIndirectCommand;
+
+/** Test verifies if operations on new buffer object PARAMETER_BUFFER_ARB works as expected.
+ **/
+class ParameterBufferOperationsCase : public deqp::TestCase
+{
+public:
+ /* Public methods */
+ ParameterBufferOperationsCase(deqp::Context& context);
+
+ virtual void init();
+ virtual tcu::TestNode::IterateResult iterate();
+
+private:
+ /* Private methods */
+ /* Private members */
+};
+
+/** Base class for specific vertex array indirect drawing classes.
+ **/
+class VertexArrayIndirectDrawingBaseCase : public deqp::TestCase
+{
+public:
+ /* Public methods */
+ VertexArrayIndirectDrawingBaseCase(deqp::Context& context, const char* name, const char* description);
+
+ virtual void init() = DE_NULL;
+ virtual void deinit() = DE_NULL;
+ virtual tcu::TestNode::IterateResult iterate();
+
+protected:
+ /* Protected methods */
+ virtual bool draw() = DE_NULL;
+ virtual bool verify();
+ virtual bool verifyErrors() = DE_NULL;
+};
+
+/** Test verifies if MultiDrawArraysIndirectCountARB function works properly.
+ **/
+class MultiDrawArraysIndirectCountCase : public VertexArrayIndirectDrawingBaseCase
+{
+public:
+ /* Public methods */
+ MultiDrawArraysIndirectCountCase(deqp::Context& context);
+
+ virtual void init();
+ virtual void deinit();
+
+protected:
+ /* Protected methods */
+ virtual bool draw();
+ virtual bool verifyErrors();
+
+ /* Protected methods */
+ GLuint m_vao;
+ GLuint m_arrayBuffer;
+ GLuint m_drawIndirectBuffer;
+ GLuint m_parameterBuffer;
+};
+
+/** Test verifies if MultiDrawArraysIndirectCountARB function works properly.
+ **/
+class MultiDrawElementsIndirectCountCase : public VertexArrayIndirectDrawingBaseCase
+{
+public:
+ /* Public methods */
+ MultiDrawElementsIndirectCountCase(deqp::Context& context);
+
+ virtual void init();
+ virtual void deinit();
+
+protected:
+ /* Protected methods */
+ virtual bool draw();
+ virtual bool verifyErrors();
+
+ /* Protected methods */
+ GLuint m_vao;
+ GLuint m_arrayBuffer;
+ GLuint m_elementBuffer;
+ GLuint m_drawIndirectBuffer;
+ GLuint m_parameterBuffer;
+};
+
+/** Test group which encapsulates all sparse buffer conformance tests */
+class IndirectParametersTests : public deqp::TestCaseGroup
+{
+public:
+ /* Public methods */
+ IndirectParametersTests(deqp::Context& context);
+
+ void init();
+
+private:
+ IndirectParametersTests(const IndirectParametersTests& other);
+ IndirectParametersTests& operator=(const IndirectParametersTests& other);
+};
+
+} /* glcts namespace */
+
+#endif // _GL4CINDIRECTPARAMETERSTESTS_HPP
diff --git a/external/openglcts/modules/gl/gl4cTestPackages.cpp b/external/openglcts/modules/gl/gl4cTestPackages.cpp
index e59b552..9166d86 100644
--- a/external/openglcts/modules/gl/gl4cTestPackages.cpp
+++ b/external/openglcts/modules/gl/gl4cTestPackages.cpp
@@ -36,6 +36,7 @@
#include "gl4cGPUShaderFP64Tests.hpp"
#include "gl4cGetTextureSubImageTests.hpp"
#include "gl4cIncompleteTextureAccessTests.hpp"
+#include "gl4cIndirectParametersTests.hpp"
#include "gl4cKHRDebugTests.hpp"
#include "gl4cMapBufferAlignmentTests.hpp"
#include "gl4cMultiBindTests.hpp"
@@ -228,6 +229,7 @@
addChild(new gl4cts::StencilTexturingTests(getContext()));
addChild(new gl4cts::SparseBufferTests(getContext()));
addChild(new gl4cts::SparseTextureTests(getContext()));
+ addChild(new gl4cts::IndirectParametersTests(getContext()));
}
catch (...)
{
diff --git a/framework/opengl/gluCallLogWrapper.inl b/framework/opengl/gluCallLogWrapper.inl
index 814f980..7e3d23c 100644
--- a/framework/opengl/gluCallLogWrapper.inl
+++ b/framework/opengl/gluCallLogWrapper.inl
@@ -3341,6 +3341,13 @@
m_gl.multiDrawArraysIndirect(mode, indirect, drawcount, stride);
}
+void CallLogWrapper::glMultiDrawArraysIndirectCountARB (glw::GLenum mode, glw::GLintptr indirect, glw::GLintptr drawcount, glw::GLsizei maxdrawcount, glw::GLsizei stride)
+{
+ if (m_enableLog)
+ m_log << TestLog::Message << "glMultiDrawArraysIndirectCountARB(" << toHex(mode) << ", " << indirect << ", " << drawcount << ", " << maxdrawcount << ", " << stride << ");" << TestLog::EndMessage;
+ m_gl.multiDrawArraysIndirectCountARB(mode, indirect, drawcount, maxdrawcount, stride);
+}
+
void CallLogWrapper::glMultiDrawElements (glw::GLenum mode, const glw::GLsizei *count, glw::GLenum type, const void *const*indices, glw::GLsizei drawcount)
{
if (m_enableLog)
@@ -3362,6 +3369,13 @@
m_gl.multiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
}
+void CallLogWrapper::glMultiDrawElementsIndirectCountARB (glw::GLenum mode, glw::GLenum type, glw::GLintptr indirect, glw::GLintptr drawcount, glw::GLsizei maxdrawcount, glw::GLsizei stride)
+{
+ if (m_enableLog)
+ m_log << TestLog::Message << "glMultiDrawElementsIndirectCountARB(" << toHex(mode) << ", " << toHex(type) << ", " << indirect << ", " << drawcount << ", " << maxdrawcount << ", " << stride << ");" << TestLog::EndMessage;
+ m_gl.multiDrawElementsIndirectCountARB(mode, type, indirect, drawcount, maxdrawcount, stride);
+}
+
void CallLogWrapper::glMultiTexBufferEXT (glw::GLenum texunit, glw::GLenum target, glw::GLenum internalformat, glw::GLuint buffer)
{
if (m_enableLog)
diff --git a/framework/opengl/gluCallLogWrapperApi.inl b/framework/opengl/gluCallLogWrapperApi.inl
index 9b5a1a0..7d93902 100644
--- a/framework/opengl/gluCallLogWrapperApi.inl
+++ b/framework/opengl/gluCallLogWrapperApi.inl
@@ -447,9 +447,11 @@
void glMinSampleShading (glw::GLfloat value);
void glMultiDrawArrays (glw::GLenum mode, const glw::GLint *first, const glw::GLsizei *count, glw::GLsizei drawcount);
void glMultiDrawArraysIndirect (glw::GLenum mode, const void *indirect, glw::GLsizei drawcount, glw::GLsizei stride);
+void glMultiDrawArraysIndirectCountARB (glw::GLenum mode, glw::GLintptr indirect, glw::GLintptr drawcount, glw::GLsizei maxdrawcount, glw::GLsizei stride);
void glMultiDrawElements (glw::GLenum mode, const glw::GLsizei *count, glw::GLenum type, const void *const*indices, glw::GLsizei drawcount);
void glMultiDrawElementsBaseVertex (glw::GLenum mode, const glw::GLsizei *count, glw::GLenum type, const void *const*indices, glw::GLsizei drawcount, const glw::GLint *basevertex);
void glMultiDrawElementsIndirect (glw::GLenum mode, glw::GLenum type, const void *indirect, glw::GLsizei drawcount, glw::GLsizei stride);
+void glMultiDrawElementsIndirectCountARB (glw::GLenum mode, glw::GLenum type, glw::GLintptr indirect, glw::GLintptr drawcount, glw::GLsizei maxdrawcount, glw::GLsizei stride);
void glMultiTexBufferEXT (glw::GLenum texunit, glw::GLenum target, glw::GLenum internalformat, glw::GLuint buffer);
void glMultiTexCoordPointerEXT (glw::GLenum texunit, glw::GLint size, glw::GLenum type, glw::GLsizei stride, const void *pointer);
void glMultiTexEnvfEXT (glw::GLenum texunit, glw::GLenum target, glw::GLenum pname, glw::GLfloat param);
diff --git a/framework/opengl/wrapper/glwApi.inl b/framework/opengl/wrapper/glwApi.inl
index 6d8f204..aea410b 100644
--- a/framework/opengl/wrapper/glwApi.inl
+++ b/framework/opengl/wrapper/glwApi.inl
@@ -447,9 +447,11 @@
#define glMinSampleShading glwMinSampleShading
#define glMultiDrawArrays glwMultiDrawArrays
#define glMultiDrawArraysIndirect glwMultiDrawArraysIndirect
+#define glMultiDrawArraysIndirectCountARB glwMultiDrawArraysIndirectCountARB
#define glMultiDrawElements glwMultiDrawElements
#define glMultiDrawElementsBaseVertex glwMultiDrawElementsBaseVertex
#define glMultiDrawElementsIndirect glwMultiDrawElementsIndirect
+#define glMultiDrawElementsIndirectCountARB glwMultiDrawElementsIndirectCountARB
#define glMultiTexBufferEXT glwMultiTexBufferEXT
#define glMultiTexCoordPointerEXT glwMultiTexCoordPointerEXT
#define glMultiTexEnvfEXT glwMultiTexEnvfEXT
@@ -1284,9 +1286,11 @@
void glwMinSampleShading (GLfloat value);
void glwMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
void glwMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+void glwMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
void glwMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);
void glwMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);
void glwMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+void glwMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
void glwMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
void glwMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer);
void glwMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
diff --git a/framework/opengl/wrapper/glwEnums.inl b/framework/opengl/wrapper/glwEnums.inl
index 7dac350..6048c6b 100644
--- a/framework/opengl/wrapper/glwEnums.inl
+++ b/framework/opengl/wrapper/glwEnums.inl
@@ -357,6 +357,8 @@
#define GL_BGRA_EXT 0x80E1
#define GL_MAX_ELEMENTS_VERTICES 0x80E8
#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_PARAMETER_BUFFER_ARB 0x80EE
+#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF
#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
#define GL_CLAMP_TO_BORDER 0x812D
#define GL_CLAMP_TO_BORDER_EXT 0x812D
diff --git a/framework/opengl/wrapper/glwFunctionTypes.inl b/framework/opengl/wrapper/glwFunctionTypes.inl
index 5d2c3f4..cf1f98b 100644
--- a/framework/opengl/wrapper/glwFunctionTypes.inl
+++ b/framework/opengl/wrapper/glwFunctionTypes.inl
@@ -447,9 +447,11 @@
typedef GLW_APICALL void (GLW_APIENTRY* glMinSampleShadingFunc) (GLfloat value);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawArraysFunc) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawArraysIndirectFunc) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawArraysIndirectCountARBFunc) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawElementsFunc) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawElementsBaseVertexFunc) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawElementsIndirectFunc) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef GLW_APICALL void (GLW_APIENTRY* glMultiDrawElementsIndirectCountARBFunc) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiTexBufferEXTFunc) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiTexCoordPointerEXTFunc) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void *pointer);
typedef GLW_APICALL void (GLW_APIENTRY* glMultiTexEnvfEXTFunc) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
diff --git a/framework/opengl/wrapper/glwFunctions.inl b/framework/opengl/wrapper/glwFunctions.inl
index 807e17e..68f7df3 100644
--- a/framework/opengl/wrapper/glwFunctions.inl
+++ b/framework/opengl/wrapper/glwFunctions.inl
@@ -447,9 +447,11 @@
glMinSampleShadingFunc minSampleShading;
glMultiDrawArraysFunc multiDrawArrays;
glMultiDrawArraysIndirectFunc multiDrawArraysIndirect;
+glMultiDrawArraysIndirectCountARBFunc multiDrawArraysIndirectCountARB;
glMultiDrawElementsFunc multiDrawElements;
glMultiDrawElementsBaseVertexFunc multiDrawElementsBaseVertex;
glMultiDrawElementsIndirectFunc multiDrawElementsIndirect;
+glMultiDrawElementsIndirectCountARBFunc multiDrawElementsIndirectCountARB;
glMultiTexBufferEXTFunc multiTexBufferEXT;
glMultiTexCoordPointerEXTFunc multiTexCoordPointerEXT;
glMultiTexEnvfEXTFunc multiTexEnvfEXT;
diff --git a/framework/opengl/wrapper/glwImpl.inl b/framework/opengl/wrapper/glwImpl.inl
index ab9d124..3f412d8 100644
--- a/framework/opengl/wrapper/glwImpl.inl
+++ b/framework/opengl/wrapper/glwImpl.inl
@@ -3556,6 +3556,14 @@
gl->multiDrawArraysIndirect(mode, indirect, drawcount, stride);
}
+void glwMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)
+{
+ const glw::Functions* gl = glw::getCurrentThreadFunctions();
+ if (!gl)
+ return;
+ gl->multiDrawArraysIndirectCountARB(mode, indirect, drawcount, maxdrawcount, stride);
+}
+
void glwMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount)
{
const glw::Functions* gl = glw::getCurrentThreadFunctions();
@@ -3580,6 +3588,14 @@
gl->multiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
}
+void glwMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)
+{
+ const glw::Functions* gl = glw::getCurrentThreadFunctions();
+ if (!gl)
+ return;
+ gl->multiDrawElementsIndirectCountARB(mode, type, indirect, drawcount, maxdrawcount, stride);
+}
+
void glwMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer)
{
const glw::Functions* gl = glw::getCurrentThreadFunctions();
diff --git a/framework/opengl/wrapper/glwInitExtGL.inl b/framework/opengl/wrapper/glwInitExtGL.inl
index 74f5226..5462ae9 100644
--- a/framework/opengl/wrapper/glwInitExtGL.inl
+++ b/framework/opengl/wrapper/glwInitExtGL.inl
@@ -695,6 +695,12 @@
gl->programParameteri = (glProgramParameteriFunc) loader->get("glProgramParameteri");
}
+if (de::contains(extSet, "GL_ARB_indirect_parameters"))
+{
+ gl->multiDrawArraysIndirectCountARB = (glMultiDrawArraysIndirectCountARBFunc) loader->get("glMultiDrawArraysIndirectCountARB");
+ gl->multiDrawElementsIndirectCountARB = (glMultiDrawElementsIndirectCountARBFunc) loader->get("glMultiDrawElementsIndirectCountARB");
+}
+
if (de::contains(extSet, "GL_ARB_internalformat_query"))
{
gl->getInternalformativ = (glGetInternalformativFunc) loader->get("glGetInternalformativ");
diff --git a/framework/platform/null/tcuNullRenderContextFuncs.inl b/framework/platform/null/tcuNullRenderContextFuncs.inl
index f9b7cb7..cd77ffc 100644
--- a/framework/platform/null/tcuNullRenderContextFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextFuncs.inl
@@ -3729,6 +3729,16 @@
}
+GLW_APICALL void GLW_APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)
+{
+ DE_UNREF(mode);
+ DE_UNREF(indirect);
+ DE_UNREF(drawcount);
+ DE_UNREF(maxdrawcount);
+ DE_UNREF(stride);
+
+}
+
GLW_APICALL void GLW_APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount)
{
DE_UNREF(mode);
@@ -3760,6 +3770,17 @@
}
+GLW_APICALL void GLW_APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)
+{
+ DE_UNREF(mode);
+ DE_UNREF(type);
+ DE_UNREF(indirect);
+ DE_UNREF(drawcount);
+ DE_UNREF(maxdrawcount);
+ DE_UNREF(stride);
+
+}
+
GLW_APICALL void GLW_APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer)
{
DE_UNREF(texunit);
diff --git a/framework/platform/null/tcuNullRenderContextInitFuncs.inl b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
index 9942f05..6eb8e50 100644
--- a/framework/platform/null/tcuNullRenderContextInitFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
@@ -447,9 +447,11 @@
gl->minSampleShading = glMinSampleShading;
gl->multiDrawArrays = glMultiDrawArrays;
gl->multiDrawArraysIndirect = glMultiDrawArraysIndirect;
+gl->multiDrawArraysIndirectCountARB = glMultiDrawArraysIndirectCountARB;
gl->multiDrawElements = glMultiDrawElements;
gl->multiDrawElementsBaseVertex = glMultiDrawElementsBaseVertex;
gl->multiDrawElementsIndirect = glMultiDrawElementsIndirect;
+gl->multiDrawElementsIndirectCountARB = glMultiDrawElementsIndirectCountARB;
gl->multiTexBufferEXT = glMultiTexBufferEXT;
gl->multiTexCoordPointerEXT = glMultiTexCoordPointerEXT;
gl->multiTexEnvfEXT = glMultiTexEnvfEXT;
diff --git a/scripts/opengl/src_util.py b/scripts/opengl/src_util.py
index 7c8b708..a94445b 100644
--- a/scripts/opengl/src_util.py
+++ b/scripts/opengl/src_util.py
@@ -96,6 +96,7 @@
'GL_ARB_draw_elements_base_vertex',
'GL_ARB_direct_state_access',
'GL_ARB_get_program_binary',
+ 'GL_ARB_indirect_parameters',
'GL_ARB_internalformat_query',
'GL_ARB_instanced_arrays',
'GL_ARB_parallel_shader_compile',