Add CTS_EXT_polygon_offset_clamp tests implementation
This is CTS_EXT_polygon_offset_clamp tests implementation.
Implemented cases list:
PolygonOffsetClampAvailability,
PolygonOffsetClampMinMax,
PolygonOffsetClampZeroInfinity.
Affects:
KHR-GL45.polygon_offset_clamp.*
KHR-GLES31.core.polygon_offset_clamp.*
Components: OpenGL, Framework
VK-GL-CTS issue: 304
Change-Id: I638ae52b6eca608dfb4acefe06eda02c4969e436
diff --git a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.5.5.x/gl45-master.txt b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.5.5.x/gl45-master.txt
index 08a1043..8be51bf 100644
--- a/external/openglcts/data/mustpass/gl/khronos_mustpass/4.5.5.x/gl45-master.txt
+++ b/external/openglcts/data/mustpass/gl/khronos_mustpass/4.5.5.x/gl45-master.txt
@@ -4936,3 +4936,6 @@
KHR-GL45.limits.max_fragment_interpolation_offset
KHR-GL45.limits.max_compute_work_group_count
KHR-GL45.limits.max_compute_work_group_size
+KHR-GL45.polygon_offset_clamp.PolygonOffsetClampAvailabilityTestCase
+KHR-GL45.polygon_offset_clamp.PolygonOffsetClampMinMaxTestCase
+KHR-GL45.polygon_offset_clamp.PolygonOffsetClampZeroInfinityTestCase
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt
index ef8a145..8b3d58b 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.4.x/gles31-khr-master.txt
@@ -1316,6 +1316,9 @@
KHR-GLES31.core.arrays_of_arrays.InteractionInterfaceArrays2
KHR-GLES31.core.arrays_of_arrays.InteractionInterfaceArrays3
KHR-GLES31.core.arrays_of_arrays.InteractionInterfaceArrays4
+KHR-GLES31.core.polygon_offset_clamp.PolygonOffsetClampAvailabilityTestCase
+KHR-GLES31.core.polygon_offset_clamp.PolygonOffsetClampMinMaxTestCase
+KHR-GLES31.core.polygon_offset_clamp.PolygonOffsetClampZeroInfinityTestCase
KHR-GLES31.core.geometry_shader.adjacency.adjacency_non_indiced_lines
KHR-GLES31.core.geometry_shader.adjacency.adjacency_indiced_lines
KHR-GLES31.core.geometry_shader.adjacency.adjacency_non_indiced_line_strip
diff --git a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
index ef8a145..8b3d58b 100644
--- a/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
+++ b/external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
@@ -1316,6 +1316,9 @@
KHR-GLES31.core.arrays_of_arrays.InteractionInterfaceArrays2
KHR-GLES31.core.arrays_of_arrays.InteractionInterfaceArrays3
KHR-GLES31.core.arrays_of_arrays.InteractionInterfaceArrays4
+KHR-GLES31.core.polygon_offset_clamp.PolygonOffsetClampAvailabilityTestCase
+KHR-GLES31.core.polygon_offset_clamp.PolygonOffsetClampMinMaxTestCase
+KHR-GLES31.core.polygon_offset_clamp.PolygonOffsetClampZeroInfinityTestCase
KHR-GLES31.core.geometry_shader.adjacency.adjacency_non_indiced_lines
KHR-GLES31.core.geometry_shader.adjacency.adjacency_indiced_lines
KHR-GLES31.core.geometry_shader.adjacency.adjacency_non_indiced_line_strip
diff --git a/external/openglcts/modules/common/CMakeLists.txt b/external/openglcts/modules/common/CMakeLists.txt
index f269a1f..c1a2636 100644
--- a/external/openglcts/modules/common/CMakeLists.txt
+++ b/external/openglcts/modules/common/CMakeLists.txt
@@ -32,6 +32,8 @@
glcNoErrorTests.hpp
glcRobustnessTests.cpp
glcRobustnessTests.hpp
+ glcPolygonOffsetClampTests.cpp
+ glcPolygonOffsetClampTests.hpp
glcRobustBufferAccessBehaviorTests.cpp
glcRobustBufferAccessBehaviorTests.hpp
glcShaderIndexingTests.cpp
diff --git a/external/openglcts/modules/common/glcPolygonOffsetClampTests.cpp b/external/openglcts/modules/common/glcPolygonOffsetClampTests.cpp
new file mode 100644
index 0000000..aaa4ef1
--- /dev/null
+++ b/external/openglcts/modules/common/glcPolygonOffsetClampTests.cpp
@@ -0,0 +1,624 @@
+/*-------------------------------------------------------------------------
+* 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 glcPolygonOffsetClampTests.cpp
+* \brief Conformance tests for the EXT_polygon_offset_clamp functionality.
+*/ /*-------------------------------------------------------------------*/
+
+#include "glcPolygonOffsetClampTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluShaderProgram.hpp"
+#include "glwEnums.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuTestLog.hpp"
+
+#include <stdio.h>
+
+using namespace glw;
+using namespace glu;
+
+namespace glcts
+{
+
+const char* poc_shader_version_450core = "#version 450 core\n\n";
+const char* poc_shader_version_310es = "#version 310 es\n\n";
+
+const char* poc_vertexColor = "in highp vec3 vertex;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex, 1);\n"
+ "}\n";
+
+const char* poc_fragmentColor = "out highp vec4 fragColor;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(1, 1, 1, 1);\n"
+ "}\n";
+
+const char* poc_vertexTexture = "in highp vec3 vertex;\n"
+ "in highp vec2 texCoord;\n"
+ "out highp vec2 varyingtexCoord;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex, 1);\n"
+ " varyingtexCoord = texCoord;\n"
+ "}\n";
+
+const char* poc_fragmentTexture = "in highp vec2 varyingtexCoord;\n"
+ "out highp vec4 fragColor;\n"
+ "\n"
+ "layout (location = 0) uniform highp sampler2D tex;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " highp vec4 v = texture(tex, varyingtexCoord);\n"
+ " int r = int(v.r * 65536.0) % 256;\n"
+ " int g = int(v.r * 65536.0) / 256;\n"
+ " fragColor = vec4(float(r) / 255.0, float(g) / 255.0, 0.0, 1.0);\n"
+ "}\n";
+
+/** Constructor.
+*
+* @param context Rendering context
+* @param name Test name
+* @param description Test description
+*/
+PolygonOffsetClampTestCaseBase::PolygonOffsetClampTestCaseBase(deqp::Context& context, const char* name,
+ const char* description)
+ : TestCase(context, name, description)
+{
+ m_extensionSupported = context.getContextInfo().isExtensionSupported("GL_EXT_polygon_offset_clamp");
+}
+
+tcu::TestNode::IterateResult PolygonOffsetClampTestCaseBase::iterate()
+{
+ if (!m_extensionSupported)
+ {
+ m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
+ return STOP;
+ }
+
+ test(m_context.getRenderContext().getFunctions());
+
+ return STOP;
+}
+
+/** Constructor.
+*
+* @param context Rendering context
+*/
+PolygonOffsetClampAvailabilityTestCase::PolygonOffsetClampAvailabilityTestCase(deqp::Context& context)
+ : PolygonOffsetClampTestCaseBase(context, "PolygonOffsetClampAvailability",
+ "Verifies if queries for GL_EXT_polygon_offset_clamp extension works properly")
+{
+}
+
+void PolygonOffsetClampAvailabilityTestCase::test(const glw::Functions& gl)
+{
+ {
+ glw::GLboolean data;
+ gl.getBooleanv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
+ }
+ {
+ glw::GLint data;
+ gl.getIntegerv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
+ }
+ {
+ glw::GLint64 data;
+ gl.getInteger64v(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
+ }
+ {
+ glw::GLfloat data;
+ gl.getFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
+ }
+
+ // OpenGL ES does not support getDoublev query
+ if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
+ {
+ glw::GLdouble data;
+ gl.getDoublev(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
+ }
+
+ gl.polygonOffsetClampEXT(1.0f, 1.0f, 0.5f);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "polygonOffsetClampEXT error occurred");
+
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+}
+
+/** Constructor.
+*
+* @param context Rendering context
+*/
+PolygonOffsetClampValueTestCaseBase::PolygonOffsetClampValueTestCaseBase(deqp::Context& context, const char* name,
+ const char* description)
+ : PolygonOffsetClampTestCaseBase(context, name, description)
+ , m_fbo(0)
+ , m_depthBuf(0)
+ , m_colorBuf(0)
+ , m_fboReadback(0)
+ , m_colorBufReadback(0)
+{
+}
+
+/** Initialization method that creates framebuffer with depth attachment
+ */
+void PolygonOffsetClampValueTestCaseBase::init()
+{
+ const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+ gl.genTextures(1, &m_depthBuf);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
+ gl.bindTexture(GL_TEXTURE_2D, m_depthBuf);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
+ gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 64, 64);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
+
+ gl.genTextures(1, &m_colorBuf);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
+ gl.bindTexture(GL_TEXTURE_2D, m_colorBuf);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
+ gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
+
+ gl.genFramebuffers(1, &m_fbo);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
+ gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuf, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
+ gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuf, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
+
+ if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
+ {
+ gl.genTextures(1, &m_colorBufReadback);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
+ gl.bindTexture(GL_TEXTURE_2D, m_colorBufReadback);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
+ gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
+ gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
+
+ gl.genFramebuffers(1, &m_fboReadback);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
+ gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBufReadback, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
+ }
+
+ gl.viewport(0, 0, 64, 64);
+}
+
+/** De-Initialization method that releases
+ */
+void PolygonOffsetClampValueTestCaseBase::deinit()
+{
+ const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+ gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
+
+ if (m_fbo)
+ gl.deleteFramebuffers(1, &m_fbo);
+ if (m_depthBuf)
+ gl.deleteTextures(1, &m_depthBuf);
+ if (m_colorBuf)
+ gl.deleteTextures(1, &m_colorBuf);
+
+ if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
+ {
+ if (m_colorBufReadback)
+ gl.deleteTextures(1, &m_colorBufReadback);
+ if (m_fboReadback)
+ gl.deleteFramebuffers(1, &m_fboReadback);
+ }
+}
+
+/** Testing method that verifies if depth values generated after polygon offset clamp are as expected.
+ *
+ * @param gl Function bindings
+ */
+void PolygonOffsetClampValueTestCaseBase::test(const glw::Functions& gl)
+{
+ const GLfloat vertices[] = { -1.0f, -1.0f, 0.5f, -1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, 1.0f, 1.0f, 0.5f };
+
+ // Prepare shader program
+ std::string vertexColor;
+ std::string fragmentColor;
+ if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
+ vertexColor = std::string(poc_shader_version_450core);
+ else
+ vertexColor = std::string(poc_shader_version_310es);
+ fragmentColor = vertexColor;
+
+ vertexColor = vertexColor + poc_vertexColor;
+ fragmentColor = fragmentColor + poc_fragmentColor;
+
+ ProgramSources testSources = makeVtxFragSources(vertexColor, fragmentColor);
+ ShaderProgram testProgram(gl, testSources);
+
+ if (!testProgram.isOk())
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "TestProgram build failed.\n"
+ << "Vertex: " << testProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
+ << "Fragment: " << testProgram.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
+ << "Program: " << testProgram.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
+
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ return;
+ }
+
+ ShaderProgram* readDepthProgram = DE_NULL;
+ GLuint readDepthProgramId = 0;
+
+ // Prepare shader program for reading depth buffer indirectly
+ if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
+ {
+ std::string vertexTexture = std::string(poc_shader_version_310es) + poc_vertexTexture;
+ std::string fragmentTexture = std::string(poc_shader_version_310es) + poc_fragmentTexture;
+
+ ProgramSources readDepthSources = makeVtxFragSources(vertexTexture, fragmentTexture);
+
+ readDepthProgram = new ShaderProgram(gl, readDepthSources);
+
+ if (!readDepthProgram->isOk())
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "ReadDepthProgram build failed.\n"
+ << "Vertex: " << readDepthProgram->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
+ << "Fragment: " << readDepthProgram->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
+ << "Program: " << readDepthProgram->getProgramInfo().infoLog << tcu::TestLog::EndMessage;
+
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ return;
+ }
+
+ readDepthProgramId = readDepthProgram->getProgram();
+ }
+
+ gl.useProgram(testProgram.getProgram());
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
+
+ GLuint vao;
+ GLuint arrayBuffer;
+
+ // Setup depth testing
+ gl.enable(GL_DEPTH_TEST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
+
+ gl.depthFunc(GL_ALWAYS);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc");
+
+ // Generate vertex array object
+ gl.genVertexArrays(1, &vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
+
+ gl.bindVertexArray(vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
+
+ // Setup vertex array buffer
+ 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, 12 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
+
+ // Setup vertex attrib pointer
+ 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");
+
+ // Bind framebuffer for drawing
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+
+ bool result = true;
+ for (uint32_t i = 0; i < m_testValues.size(); ++i)
+ {
+ // Prepare verification variables
+ GLfloat depthValue = 0.0f;
+ GLfloat depthValueOffset = 0.0f;
+ GLfloat depthValueOffsetClamp = 0.0f;
+
+ // Draw reference polygon
+ gl.disable(GL_POLYGON_OFFSET_FILL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
+
+ gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
+
+ // Get reference depth value
+ depthValue = readDepthValue(gl, readDepthProgramId);
+
+ // Draw polygon with depth offset
+ gl.enable(GL_POLYGON_OFFSET_FILL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
+
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+
+ gl.polygonOffset(m_testValues[i].factor, m_testValues[i].units);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glPolygonOffset");
+
+ gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
+
+ depthValueOffset = readDepthValue(gl, readDepthProgramId);
+
+ // Draw reference polygon
+ gl.disable(GL_POLYGON_OFFSET_FILL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
+
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+
+ gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
+
+ gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
+
+ // Draw polygon with depth offset
+ gl.enable(GL_POLYGON_OFFSET_FILL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
+
+ gl.polygonOffsetClampEXT(m_testValues[i].factor, m_testValues[i].units, m_testValues[i].clamp);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glPolygonOffsetClampEXT");
+
+ gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
+
+ depthValueOffsetClamp = readDepthValue(gl, readDepthProgramId);
+
+ // Verify results
+ result = result && verify(i, depthValue, depthValueOffset, depthValueOffsetClamp);
+ }
+
+ // Cleanup
+ gl.disableVertexAttribArray(0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
+
+ gl.deleteVertexArrays(1, &arrayBuffer);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
+
+ gl.deleteVertexArrays(1, &vao);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
+
+ gl.disable(GL_POLYGON_OFFSET_FILL);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
+
+ if (readDepthProgram)
+ delete readDepthProgram;
+
+ if (result)
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ else
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+}
+
+/** Method .
+ *
+ * @param gl Function bindings
+ */
+float PolygonOffsetClampValueTestCaseBase::readDepthValue(const glw::Functions& gl, const GLuint readDepthProgramId)
+{
+ GLfloat depthValue = 0.0f;
+
+ if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
+ {
+ gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthValue);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
+ }
+ // OpenGL ES does not support reading pixels directly from depth buffer
+ else
+ {
+ // Bind framebuffer for readback
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+
+ gl.disable(GL_DEPTH_TEST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
+
+ gl.useProgram(readDepthProgramId);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
+
+ gl.activeTexture(GL_TEXTURE0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
+ gl.bindTexture(GL_TEXTURE_2D, m_depthBuf);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
+ gl.uniform1i(0, 0);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
+
+ gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
+
+ GLubyte pixels[4];
+ gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
+
+ gl.enable(GL_DEPTH_TEST);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
+
+ // Convert read depth value to GLfloat normalized
+ depthValue = (GLfloat)(pixels[0] + pixels[1] * 256) / 0xFFFF;
+
+ // Bind framebuffer for drawing
+ gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+ }
+
+ return depthValue;
+}
+
+/** Constructor.
+*
+* @param context Rendering context
+*/
+PolygonOffsetClampMinMaxTestCase::PolygonOffsetClampMinMaxTestCase(deqp::Context& context)
+ : PolygonOffsetClampValueTestCaseBase(
+ context, "PolygonOffsetClampMinMax",
+ "Verifies if polygon offset clamp works as expected for non-zero, finite clamp values")
+{
+}
+
+/** Initialization method that fills polygonOffset* testing values
+ */
+void PolygonOffsetClampMinMaxTestCase::init()
+{
+ PolygonOffsetClampValueTestCaseBase::init();
+
+ m_testValues.clear();
+ m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, -0.0001f)); // Min offset case
+ m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, 0.0001f)); // Max offset case
+}
+
+/** Verification method that determines if depth values are as expected
+ *
+ * @param caseNo Case iteration number
+ * @param depth Reference depth value
+ * @param offsetDepth Case iteration number
+ * @param offsetClampDepth Case iteration number
+ */
+bool PolygonOffsetClampMinMaxTestCase::verify(uint32_t caseNo, GLfloat depth, GLfloat offsetDepth,
+ GLfloat offsetClampDepth)
+{
+ // Min offset case
+ if (caseNo == 0)
+ {
+ if (depth <= offsetDepth || depth <= offsetClampDepth || offsetDepth >= offsetClampDepth)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MIN offset test.\n"
+ << "Expected result: "
+ << "refDepth[" << depth << "] > "
+ << "offsetClampDepth[" << offsetClampDepth << "] > "
+ << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage;
+
+ return false;
+ }
+ }
+ // Max offset case
+ else if (caseNo == 1)
+ {
+ if (depth >= offsetDepth || depth >= offsetClampDepth || offsetDepth <= offsetClampDepth)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MAX offset test.\n"
+ << "Expected result: "
+ << "refDepth[" << depth << "] < "
+ << "offsetClampDepth[" << offsetClampDepth << "] < "
+ << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage;
+
+ return false;
+ }
+ }
+ // Undefined case
+ else
+ return false;
+
+ return true;
+}
+
+/** Constructor.
+*
+* @param context Rendering context
+*/
+PolygonOffsetClampZeroInfinityTestCase::PolygonOffsetClampZeroInfinityTestCase(deqp::Context& context)
+ : PolygonOffsetClampValueTestCaseBase(
+ context, "PolygonOffsetClampZeroInfinity",
+ "Verifies if polygon offset clamp works as expected for zero and infinite clamp values")
+{
+}
+
+/** Initialization method that fills polygonOffset* testing values
+ */
+void PolygonOffsetClampZeroInfinityTestCase::init()
+{
+ PolygonOffsetClampValueTestCaseBase::init();
+
+ m_testValues.clear();
+ m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, 0.0f)); // Min offset, zero clamp case
+ m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, -INFINITY)); // Min Offset, infinity clamp case
+ m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, 0.0f)); // Max offset, zero clamp case
+ m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, INFINITY)); // Max Offset, infinity clamp case
+}
+
+bool PolygonOffsetClampZeroInfinityTestCase::verify(uint32_t caseNo, GLfloat depth, GLfloat offsetDepth,
+ GLfloat offsetClampDepth)
+{
+ DE_UNREF(caseNo);
+
+ if (depth == offsetDepth || depth == offsetClampDepth || offsetDepth != offsetClampDepth)
+ {
+ m_testCtx.getLog() << tcu::TestLog::Message
+ << "PolygonOffsetClampEXT failed at Zero/Infinity offset clamp test.\n"
+ << "Expected result: "
+ << "refDepth[" << depth << "] != "
+ << "(offsetClampDepth[" << offsetClampDepth << "] == "
+ << "offsetDepth[" << offsetDepth << "])" << tcu::TestLog::EndMessage;
+
+ return false;
+ }
+
+ return true;
+}
+
+/** Constructor.
+*
+* @param context Rendering context.
+*/
+PolygonOffsetClamp::PolygonOffsetClamp(deqp::Context& context)
+ : TestCaseGroup(context, "polygon_offset_clamp",
+ "Verify conformance of CTS_EXT_polygon_offset_clamp implementation")
+{
+}
+
+/** Initializes the test group contents. */
+void PolygonOffsetClamp::init()
+{
+ addChild(new PolygonOffsetClampAvailabilityTestCase(m_context));
+ addChild(new PolygonOffsetClampMinMaxTestCase(m_context));
+ addChild(new PolygonOffsetClampZeroInfinityTestCase(m_context));
+}
+} /* glcts namespace */
diff --git a/external/openglcts/modules/common/glcPolygonOffsetClampTests.hpp b/external/openglcts/modules/common/glcPolygonOffsetClampTests.hpp
new file mode 100644
index 0000000..999957d
--- /dev/null
+++ b/external/openglcts/modules/common/glcPolygonOffsetClampTests.hpp
@@ -0,0 +1,153 @@
+#ifndef _GLCPOLYGONOFFSETCLAMPTESTS_HPP
+#define _GLCPOLYGONOFFSETCLAMPTESTS_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 glcPolygonOffsetClampTests.hpp
+* \brief Conformance tests for the EXT_polygon_offset_clamp functionality.
+*/ /*-------------------------------------------------------------------*/
+
+#include "esextcTestCaseBase.hpp"
+#include "glcTestCase.hpp"
+#include "gluShaderProgram.hpp"
+
+#include <string>
+
+using namespace glw;
+
+namespace glcts
+{
+
+struct PolygonOffsetClampValues
+{
+ GLfloat factor;
+ GLfloat units;
+ GLfloat clamp;
+
+ PolygonOffsetClampValues(GLfloat _f, GLfloat _u, GLfloat _c) : factor(_f), units(_u), clamp(_c)
+ {
+ }
+};
+
+/** Tests base class
+**/
+class PolygonOffsetClampTestCaseBase : public deqp::TestCase
+{
+public:
+ /* Public methods */
+ PolygonOffsetClampTestCaseBase(deqp::Context& context, const char* name, const char* description);
+
+ virtual tcu::TestNode::IterateResult iterate();
+
+protected:
+ /* Protected methods */
+ virtual void test(const glw::Functions& gl) = DE_NULL;
+
+ /* Protected members */
+ bool m_extensionSupported;
+};
+
+/** Test verifies if polygon offset clamp works as expected for non-zero, finite clamp values
+**/
+class PolygonOffsetClampAvailabilityTestCase : public PolygonOffsetClampTestCaseBase
+{
+public:
+ /* Public methods */
+ PolygonOffsetClampAvailabilityTestCase(deqp::Context& context);
+
+protected:
+ /* Protected methods */
+ void test(const glw::Functions& gl);
+};
+
+/** Base class for polygon offset clamp depth values verifying
+**/
+class PolygonOffsetClampValueTestCaseBase : public PolygonOffsetClampTestCaseBase
+{
+public:
+ /* Public methods */
+ PolygonOffsetClampValueTestCaseBase(deqp::Context& context, const char* name, const char* description);
+
+ virtual void init();
+ virtual void deinit();
+
+protected:
+ /* Protected members */
+ GLuint m_fbo;
+ GLuint m_depthBuf;
+ GLuint m_colorBuf;
+ GLuint m_fboReadback;
+ GLuint m_colorBufReadback;
+
+ std::vector<PolygonOffsetClampValues> m_testValues;
+
+ /* Protected methods */
+ void test(const glw::Functions& gl);
+
+ float readDepthValue(const glw::Functions& gl, const GLuint readDepthProgramId);
+
+ virtual bool verify(uint32_t caseNo, GLfloat depth, GLfloat offsetDepth, GLfloat offsetClampDepth) = DE_NULL;
+};
+
+/** Test verifies if polygon offset clamp works as expected for zero and infinite clamp values
+**/
+class PolygonOffsetClampMinMaxTestCase : public PolygonOffsetClampValueTestCaseBase
+{
+public:
+ /* Public methods */
+ PolygonOffsetClampMinMaxTestCase(deqp::Context& context);
+
+ void init();
+
+protected:
+ /* Protected methods */
+ bool verify(uint32_t caseNo, GLfloat depth, GLfloat offsetDepth, GLfloat offsetClampDepth);
+};
+
+/** Test verifies ...
+**/
+class PolygonOffsetClampZeroInfinityTestCase : public PolygonOffsetClampValueTestCaseBase
+{
+public:
+ /* Public methods */
+ PolygonOffsetClampZeroInfinityTestCase(deqp::Context& context);
+
+ void init();
+
+protected:
+ /* Protected methods */
+ bool verify(uint32_t caseNo, GLfloat depth, GLfloat offsetDepth, GLfloat offsetClampDepth);
+};
+
+/** Test group which encapsulates all ARB_shader_group_vote conformance tests */
+class PolygonOffsetClamp : public deqp::TestCaseGroup
+{
+public:
+ /* Public methods */
+ PolygonOffsetClamp(deqp::Context& context);
+
+ void init();
+
+private:
+ PolygonOffsetClamp(const PolygonOffsetClamp& other);
+};
+
+} /* glcts namespace */
+
+#endif // _GLCPOLYGONOFFSETCLAMPTESTS_HPP
diff --git a/external/openglcts/modules/gl/gl4cTestPackages.cpp b/external/openglcts/modules/gl/gl4cTestPackages.cpp
index 904b68c..3415dd3 100644
--- a/external/openglcts/modules/gl/gl4cTestPackages.cpp
+++ b/external/openglcts/modules/gl/gl4cTestPackages.cpp
@@ -71,6 +71,7 @@
#include "glcBlendEquationAdvancedTests.hpp"
#include "glcExposedExtensionsTests.hpp"
#include "glcInfoTests.hpp"
+#include "glcPolygonOffsetClampTests.hpp"
#include "glcRobustBufferAccessBehaviorTests.hpp"
#include "glcSampleVariablesTests.hpp"
#include "glcShaderIntegerMixTests.hpp"
@@ -364,6 +365,7 @@
addChild(new gl4cts::ShaderDrawParametersTests(getContext()));
addChild(new gl4cts::ShaderViewportLayerArray(getContext()));
addChild(new gl4cts::LimitsTests(getContext()));
+ addChild(new glcts::PolygonOffsetClamp(getContext()));
}
catch (...)
{
diff --git a/external/openglcts/modules/gles31/es31cTestPackage.cpp b/external/openglcts/modules/gles31/es31cTestPackage.cpp
index 65fd006..c197b29 100644
--- a/external/openglcts/modules/gles31/es31cTestPackage.cpp
+++ b/external/openglcts/modules/gles31/es31cTestPackage.cpp
@@ -44,6 +44,7 @@
#include "es31cVertexAttribBindingTests.hpp"
#include "glcBlendEquationAdvancedTests.hpp"
#include "glcInfoTests.hpp"
+#include "glcPolygonOffsetClampTests.hpp"
#include "glcSampleVariablesTests.hpp"
#include "glcShaderIntegerMixTests.hpp"
#include "glcShaderMultisampleInterpolationTests.hpp"
@@ -187,6 +188,7 @@
coreGroup->addChild(new glcts::ProgramInterfaceQueryTests(getContext()));
coreGroup->addChild(new glcts::FramebufferNoAttachmentsTests(getContext()));
coreGroup->addChild(new glcts::ArrayOfArraysTestGroup(getContext()));
+ coreGroup->addChild(new glcts::PolygonOffsetClamp(getContext()));
glcts::ExtParameters extParams(glu::GLSL_VERSION_310_ES, glcts::EXTENSIONTYPE_OES);
coreGroup->addChild(new glcts::GeometryShaderTests(getContext(), extParams));
diff --git a/framework/opengl/gluCallLogWrapper.inl b/framework/opengl/gluCallLogWrapper.inl
index 9956c79..e9ca3cd 100644
--- a/framework/opengl/gluCallLogWrapper.inl
+++ b/framework/opengl/gluCallLogWrapper.inl
@@ -4047,6 +4047,13 @@
m_gl.polygonOffset(factor, units);
}
+void CallLogWrapper::glPolygonOffsetClampEXT (glw::GLfloat factor, glw::GLfloat units, glw::GLfloat clamp)
+{
+ if (m_enableLog)
+ m_log << TestLog::Message << "glPolygonOffsetClampEXT(" << factor << ", " << units << ", " << clamp << ");" << TestLog::EndMessage;
+ m_gl.polygonOffsetClampEXT(factor, units, clamp);
+}
+
void CallLogWrapper::glPopDebugGroup (void)
{
if (m_enableLog)
diff --git a/framework/opengl/gluCallLogWrapperApi.inl b/framework/opengl/gluCallLogWrapperApi.inl
index 9911fe4..fa824f5 100644
--- a/framework/opengl/gluCallLogWrapperApi.inl
+++ b/framework/opengl/gluCallLogWrapperApi.inl
@@ -547,6 +547,7 @@
void glPointSize (glw::GLfloat size);
void glPolygonMode (glw::GLenum face, glw::GLenum mode);
void glPolygonOffset (glw::GLfloat factor, glw::GLfloat units);
+void glPolygonOffsetClampEXT (glw::GLfloat factor, glw::GLfloat units, glw::GLfloat clamp);
void glPopDebugGroup (void);
void glPopGroupMarkerEXT (void);
void glPrimitiveBoundingBox (glw::GLfloat minX, glw::GLfloat minY, glw::GLfloat minZ, glw::GLfloat minW, glw::GLfloat maxX, glw::GLfloat maxY, glw::GLfloat maxZ, glw::GLfloat maxW);
diff --git a/framework/opengl/wrapper/glwApi.inl b/framework/opengl/wrapper/glwApi.inl
index 086fafc..1000cf0 100644
--- a/framework/opengl/wrapper/glwApi.inl
+++ b/framework/opengl/wrapper/glwApi.inl
@@ -547,6 +547,7 @@
#define glPointSize glwPointSize
#define glPolygonMode glwPolygonMode
#define glPolygonOffset glwPolygonOffset
+#define glPolygonOffsetClampEXT glwPolygonOffsetClampEXT
#define glPopDebugGroup glwPopDebugGroup
#define glPopGroupMarkerEXT glwPopGroupMarkerEXT
#define glPrimitiveBoundingBox glwPrimitiveBoundingBox
@@ -1435,6 +1436,7 @@
void glwPointSize (GLfloat size);
void glwPolygonMode (GLenum face, GLenum mode);
void glwPolygonOffset (GLfloat factor, GLfloat units);
+void glwPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp);
void glwPopDebugGroup ();
void glwPopGroupMarkerEXT ();
void glwPrimitiveBoundingBox (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
diff --git a/framework/opengl/wrapper/glwEnums.inl b/framework/opengl/wrapper/glwEnums.inl
index 758b691..933ea17 100644
--- a/framework/opengl/wrapper/glwEnums.inl
+++ b/framework/opengl/wrapper/glwEnums.inl
@@ -1198,6 +1198,7 @@
#define GL_QUERY_NO_WAIT_INVERTED 0x8E18
#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19
#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A
+#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B
#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E
#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
diff --git a/framework/opengl/wrapper/glwFunctionTypes.inl b/framework/opengl/wrapper/glwFunctionTypes.inl
index e3832c6..9aedbc2 100644
--- a/framework/opengl/wrapper/glwFunctionTypes.inl
+++ b/framework/opengl/wrapper/glwFunctionTypes.inl
@@ -547,6 +547,7 @@
typedef GLW_APICALL void (GLW_APIENTRY* glPointSizeFunc) (GLfloat size);
typedef GLW_APICALL void (GLW_APIENTRY* glPolygonModeFunc) (GLenum face, GLenum mode);
typedef GLW_APICALL void (GLW_APIENTRY* glPolygonOffsetFunc) (GLfloat factor, GLfloat units);
+typedef GLW_APICALL void (GLW_APIENTRY* glPolygonOffsetClampEXTFunc) (GLfloat factor, GLfloat units, GLfloat clamp);
typedef GLW_APICALL void (GLW_APIENTRY* glPopDebugGroupFunc) (void);
typedef GLW_APICALL void (GLW_APIENTRY* glPopGroupMarkerEXTFunc) (void);
typedef GLW_APICALL void (GLW_APIENTRY* glPrimitiveBoundingBoxFunc) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
diff --git a/framework/opengl/wrapper/glwFunctions.inl b/framework/opengl/wrapper/glwFunctions.inl
index 996752d..2ae9a2b 100644
--- a/framework/opengl/wrapper/glwFunctions.inl
+++ b/framework/opengl/wrapper/glwFunctions.inl
@@ -547,6 +547,7 @@
glPointSizeFunc pointSize;
glPolygonModeFunc polygonMode;
glPolygonOffsetFunc polygonOffset;
+glPolygonOffsetClampEXTFunc polygonOffsetClampEXT;
glPopDebugGroupFunc popDebugGroup;
glPopGroupMarkerEXTFunc popGroupMarkerEXT;
glPrimitiveBoundingBoxFunc primitiveBoundingBox;
diff --git a/framework/opengl/wrapper/glwImpl.inl b/framework/opengl/wrapper/glwImpl.inl
index 86a6b84..fecc729 100644
--- a/framework/opengl/wrapper/glwImpl.inl
+++ b/framework/opengl/wrapper/glwImpl.inl
@@ -4356,6 +4356,14 @@
gl->polygonOffset(factor, units);
}
+void glwPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp)
+{
+ const glw::Functions* gl = glw::getCurrentThreadFunctions();
+ if (!gl)
+ return;
+ gl->polygonOffsetClampEXT(factor, units, clamp);
+}
+
void glwPopDebugGroup (void)
{
const glw::Functions* gl = glw::getCurrentThreadFunctions();
diff --git a/framework/opengl/wrapper/glwInitExtES.inl b/framework/opengl/wrapper/glwInitExtES.inl
index bdfa5f1..df6c1e4 100644
--- a/framework/opengl/wrapper/glwInitExtES.inl
+++ b/framework/opengl/wrapper/glwInitExtES.inl
@@ -116,6 +116,11 @@
gl->pushGroupMarkerEXT = (glPushGroupMarkerEXTFunc) loader->get("glPushGroupMarkerEXT");
}
+if (de::contains(extSet, "GL_EXT_polygon_offset_clamp"))
+{
+ gl->polygonOffsetClampEXT = (glPolygonOffsetClampEXTFunc) loader->get("glPolygonOffsetClampEXT");
+}
+
if (de::contains(extSet, "GL_OES_EGL_image"))
{
gl->eglImageTargetRenderbufferStorageOES = (glEGLImageTargetRenderbufferStorageOESFunc) loader->get("glEGLImageTargetRenderbufferStorageOES");
diff --git a/framework/opengl/wrapper/glwInitExtGL.inl b/framework/opengl/wrapper/glwInitExtGL.inl
index 2ed48f0..1da2c34 100644
--- a/framework/opengl/wrapper/glwInitExtGL.inl
+++ b/framework/opengl/wrapper/glwInitExtGL.inl
@@ -557,6 +557,11 @@
gl->pushGroupMarkerEXT = (glPushGroupMarkerEXTFunc) loader->get("glPushGroupMarkerEXT");
}
+if (de::contains(extSet, "GL_EXT_polygon_offset_clamp"))
+{
+ gl->polygonOffsetClampEXT = (glPolygonOffsetClampEXTFunc) loader->get("glPolygonOffsetClampEXT");
+}
+
if (de::contains(extSet, "GL_ARB_clip_control"))
{
gl->clipControl = (glClipControlFunc) loader->get("glClipControl");
diff --git a/framework/platform/null/tcuNullRenderContextFuncs.inl b/framework/platform/null/tcuNullRenderContextFuncs.inl
index 08f15c6..cb470f2 100644
--- a/framework/platform/null/tcuNullRenderContextFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextFuncs.inl
@@ -4669,6 +4669,14 @@
}
+GLW_APICALL void GLW_APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp)
+{
+ DE_UNREF(factor);
+ DE_UNREF(units);
+ DE_UNREF(clamp);
+
+}
+
GLW_APICALL void GLW_APIENTRY glPopDebugGroup (void)
{
diff --git a/framework/platform/null/tcuNullRenderContextInitFuncs.inl b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
index a4ed40f..1ce3664 100644
--- a/framework/platform/null/tcuNullRenderContextInitFuncs.inl
+++ b/framework/platform/null/tcuNullRenderContextInitFuncs.inl
@@ -547,6 +547,7 @@
gl->pointSize = glPointSize;
gl->polygonMode = glPolygonMode;
gl->polygonOffset = glPolygonOffset;
+gl->polygonOffsetClampEXT = glPolygonOffsetClampEXT;
gl->popDebugGroup = glPopDebugGroup;
gl->popGroupMarkerEXT = glPopGroupMarkerEXT;
gl->primitiveBoundingBox = glPrimitiveBoundingBox;
diff --git a/scripts/opengl/src_util.py b/scripts/opengl/src_util.py
index 56df340..a74b3a2 100644
--- a/scripts/opengl/src_util.py
+++ b/scripts/opengl/src_util.py
@@ -73,6 +73,7 @@
'GL_EXT_texture_sRGB_R8',
'GL_EXT_texture_sRGB_RG8',
'GL_EXT_debug_marker',
+ 'GL_EXT_polygon_offset_clamp',
'GL_IMG_texture_compression_pvrtc',
'GL_OES_EGL_image',
'GL_OES_EGL_image_external',