Fix to PolygonOffsetClamp windows build
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcPolygonOffsetClampTests.cpp
1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2017 The Khronos Group Inc.
6 *
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
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 */ /*!
20 * \file  glcPolygonOffsetClampTests.cpp
21 * \brief Conformance tests for the EXT_polygon_offset_clamp functionality.
22 */ /*-------------------------------------------------------------------*/
23
24 #include "glcPolygonOffsetClampTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "glwEnums.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "tcuTestLog.hpp"
30
31 #include <stdio.h>
32
33 using namespace glw;
34 using namespace glu;
35
36 namespace glcts
37 {
38
39 const char* poc_shader_version_450core = "#version 450 core\n\n";
40 const char* poc_shader_version_310es   = "#version 310 es\n\n";
41
42 const char* poc_vertexColor = "in highp vec3 vertex;\n"
43                                                           "\n"
44                                                           "void main()\n"
45                                                           "{\n"
46                                                           "    gl_Position = vec4(vertex, 1);\n"
47                                                           "}\n";
48
49 const char* poc_fragmentColor = "out highp vec4 fragColor;\n"
50                                                                 "\n"
51                                                                 "void main()\n"
52                                                                 "{\n"
53                                                                 "    fragColor = vec4(1, 1, 1, 1);\n"
54                                                                 "}\n";
55
56 const char* poc_vertexTexture = "in highp vec3 vertex;\n"
57                                                                 "in highp vec2 texCoord;\n"
58                                                                 "out highp vec2 varyingtexCoord;\n"
59                                                                 "\n"
60                                                                 "void main()\n"
61                                                                 "{\n"
62                                                                 "    gl_Position = vec4(vertex, 1);\n"
63                                                                 "    varyingtexCoord = texCoord;\n"
64                                                                 "}\n";
65
66 const char* poc_fragmentTexture = "in highp vec2 varyingtexCoord;\n"
67                                                                   "out highp vec4 fragColor;\n"
68                                                                   "\n"
69                                                                   "layout (location = 0) uniform highp sampler2D tex;\n"
70                                                                   "\n"
71                                                                   "void main()\n"
72                                                                   "{\n"
73                                                                   "    highp vec4 v = texture(tex, varyingtexCoord);\n"
74                                                                   "    int r = int(v.r * 65536.0) % 256;\n"
75                                                                   "    int g = int(v.r * 65536.0) / 256;\n"
76                                                                   "    fragColor = vec4(float(r) / 255.0, float(g) / 255.0, 0.0, 1.0);\n"
77                                                                   "}\n";
78
79 /** Constructor.
80 *
81 *  @param context Rendering context
82 *  @param name Test name
83 *  @param description Test description
84 */
85 PolygonOffsetClampTestCaseBase::PolygonOffsetClampTestCaseBase(deqp::Context& context, const char* name,
86                                                                                                                            const char* description)
87         : TestCase(context, name, description)
88 {
89         m_extensionSupported = context.getContextInfo().isExtensionSupported("GL_EXT_polygon_offset_clamp");
90 }
91
92 tcu::TestNode::IterateResult PolygonOffsetClampTestCaseBase::iterate()
93 {
94         if (!m_extensionSupported)
95         {
96                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
97                 return STOP;
98         }
99
100         test(m_context.getRenderContext().getFunctions());
101
102         return STOP;
103 }
104
105 /** Constructor.
106 *
107 *  @param context Rendering context
108 */
109 PolygonOffsetClampAvailabilityTestCase::PolygonOffsetClampAvailabilityTestCase(deqp::Context& context)
110         : PolygonOffsetClampTestCaseBase(context, "PolygonOffsetClampAvailability",
111                                                                          "Verifies if queries for GL_EXT_polygon_offset_clamp extension works properly")
112 {
113 }
114
115 void PolygonOffsetClampAvailabilityTestCase::test(const glw::Functions& gl)
116 {
117         {
118                 glw::GLboolean data;
119                 gl.getBooleanv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
120                 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
121         }
122         {
123                 glw::GLint data;
124                 gl.getIntegerv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
125                 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
126         }
127         {
128                 glw::GLint64 data;
129                 gl.getInteger64v(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
130                 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
131         }
132         {
133                 glw::GLfloat data;
134                 gl.getFloatv(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
135                 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
136         }
137
138         // OpenGL ES does not support getDoublev query
139         if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
140         {
141                 glw::GLdouble data;
142                 gl.getDoublev(GL_POLYGON_OFFSET_CLAMP_EXT, &data);
143                 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv error occurred");
144         }
145
146         gl.polygonOffsetClamp(1.0f, 1.0f, 0.5f);
147         GLU_EXPECT_NO_ERROR(gl.getError(), "polygonOffsetClamp error occurred");
148
149         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
150 }
151
152 /** Constructor.
153 *
154 *  @param context Rendering context
155 */
156 PolygonOffsetClampValueTestCaseBase::PolygonOffsetClampValueTestCaseBase(deqp::Context& context, const char* name,
157                                                                                                                                                  const char* description)
158         : PolygonOffsetClampTestCaseBase(context, name, description)
159         , m_fbo(0)
160         , m_depthBuf(0)
161         , m_colorBuf(0)
162         , m_fboReadback(0)
163         , m_colorBufReadback(0)
164 {
165 }
166
167 /** Initialization method that creates framebuffer with depth attachment
168  */
169 void PolygonOffsetClampValueTestCaseBase::init()
170 {
171         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
172
173         gl.genTextures(1, &m_depthBuf);
174         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
175         gl.bindTexture(GL_TEXTURE_2D, m_depthBuf);
176         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
177         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 64, 64);
178         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
179         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
180         GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
181         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
182         GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
183
184         gl.genTextures(1, &m_colorBuf);
185         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
186         gl.bindTexture(GL_TEXTURE_2D, m_colorBuf);
187         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
188         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
189         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
190         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
191         GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
192         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
193         GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
194
195         gl.genFramebuffers(1, &m_fbo);
196         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
197         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
198         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
199         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuf, 0);
200         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
201         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuf, 0);
202         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
203
204         if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
205         {
206                 gl.genTextures(1, &m_colorBufReadback);
207                 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
208                 gl.bindTexture(GL_TEXTURE_2D, m_colorBufReadback);
209                 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
210                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
211                 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
212                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
213                 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
214                 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
215                 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");
216
217                 gl.genFramebuffers(1, &m_fboReadback);
218                 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
219                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback);
220                 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
221                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBufReadback, 0);
222                 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
223         }
224
225         gl.viewport(0, 0, 64, 64);
226 }
227
228 /** De-Initialization method that releases
229  */
230 void PolygonOffsetClampValueTestCaseBase::deinit()
231 {
232         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
233
234         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
235         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
236
237         if (m_fbo)
238                 gl.deleteFramebuffers(1, &m_fbo);
239         if (m_depthBuf)
240                 gl.deleteTextures(1, &m_depthBuf);
241         if (m_colorBuf)
242                 gl.deleteTextures(1, &m_colorBuf);
243
244         if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
245         {
246                 if (m_colorBufReadback)
247                         gl.deleteTextures(1, &m_colorBufReadback);
248                 if (m_fboReadback)
249                         gl.deleteFramebuffers(1, &m_fboReadback);
250         }
251 }
252
253 /** Testing method that verifies if depth values generated after polygon offset clamp are as expected.
254  *
255  *  @param gl   Function bindings
256  */
257 void PolygonOffsetClampValueTestCaseBase::test(const glw::Functions& gl)
258 {
259         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 };
260
261         // Prepare shader program
262         std::string vertexColor;
263         std::string fragmentColor;
264         if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
265                 vertexColor = std::string(poc_shader_version_450core);
266         else
267                 vertexColor = std::string(poc_shader_version_310es);
268         fragmentColor   = vertexColor;
269
270         vertexColor   = vertexColor + poc_vertexColor;
271         fragmentColor = fragmentColor + poc_fragmentColor;
272
273         ProgramSources testSources = makeVtxFragSources(vertexColor, fragmentColor);
274         ShaderProgram  testProgram(gl, testSources);
275
276         if (!testProgram.isOk())
277         {
278                 m_testCtx.getLog() << tcu::TestLog::Message << "TestProgram build failed.\n"
279                                                    << "Vertex: " << testProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
280                                                    << "Fragment: " << testProgram.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
281                                                    << "Program: " << testProgram.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
282
283                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
284                 return;
285         }
286
287         ShaderProgram* readDepthProgram   = DE_NULL;
288         GLuint             readDepthProgramId = 0;
289
290         // Prepare shader program for reading depth buffer indirectly
291         if (!glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
292         {
293                 std::string vertexTexture   = std::string(poc_shader_version_310es) + poc_vertexTexture;
294                 std::string fragmentTexture = std::string(poc_shader_version_310es) + poc_fragmentTexture;
295
296                 ProgramSources readDepthSources = makeVtxFragSources(vertexTexture, fragmentTexture);
297
298                 readDepthProgram = new ShaderProgram(gl, readDepthSources);
299
300                 if (!readDepthProgram->isOk())
301                 {
302                         m_testCtx.getLog() << tcu::TestLog::Message << "ReadDepthProgram build failed.\n"
303                                                            << "Vertex: " << readDepthProgram->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
304                                                            << "Fragment: " << readDepthProgram->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
305                                                            << "Program: " << readDepthProgram->getProgramInfo().infoLog << tcu::TestLog::EndMessage;
306
307                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
308                         return;
309                 }
310
311                 readDepthProgramId = readDepthProgram->getProgram();
312         }
313
314         gl.useProgram(testProgram.getProgram());
315         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
316
317         GLuint vao;
318         GLuint arrayBuffer;
319
320         // Setup depth testing
321         gl.enable(GL_DEPTH_TEST);
322         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
323
324         gl.depthFunc(GL_ALWAYS);
325         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc");
326
327         // Generate vertex array object
328         gl.genVertexArrays(1, &vao);
329         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
330
331         gl.bindVertexArray(vao);
332         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
333
334         // Setup vertex array buffer
335         gl.genBuffers(1, &arrayBuffer);
336         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
337
338         gl.bindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
339         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
340
341         gl.bufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
342         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
343
344         // Setup vertex attrib pointer
345         gl.enableVertexAttribArray(0);
346         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
347
348         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
349         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
350
351         // Bind framebuffer for drawing
352         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
353         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
354
355         bool result = true;
356         for (GLuint i = 0; i < m_testValues.size(); ++i)
357         {
358                 // Prepare verification variables
359                 GLfloat depthValue                        = 0.0f;
360                 GLfloat depthValueOffset          = 0.0f;
361                 GLfloat depthValueOffsetClamp = 0.0f;
362
363                 // Draw reference polygon
364                 gl.disable(GL_POLYGON_OFFSET_FILL);
365                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
366
367                 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
368                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
369
370                 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
371                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
372
373                 // Get reference depth value
374                 depthValue = readDepthValue(gl, readDepthProgramId);
375
376                 // Draw polygon with depth offset
377                 gl.enable(GL_POLYGON_OFFSET_FILL);
378                 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
379
380                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
381                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
382
383                 gl.polygonOffset(m_testValues[i].factor, m_testValues[i].units);
384                 GLU_EXPECT_NO_ERROR(gl.getError(), "glPolygonOffset");
385
386                 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
387                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
388
389                 depthValueOffset = readDepthValue(gl, readDepthProgramId);
390
391                 // Draw reference polygon
392                 gl.disable(GL_POLYGON_OFFSET_FILL);
393                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
394
395                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
396                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
397
398                 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
399                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
400
401                 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
402                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
403
404                 // Draw polygon with depth offset
405                 gl.enable(GL_POLYGON_OFFSET_FILL);
406                 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
407
408                 gl.polygonOffsetClamp(m_testValues[i].factor, m_testValues[i].units, m_testValues[i].clamp);
409                 GLU_EXPECT_NO_ERROR(gl.getError(), "glPolygonOffsetClampEXT");
410
411                 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
412                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
413
414                 depthValueOffsetClamp = readDepthValue(gl, readDepthProgramId);
415
416                 // Verify results
417                 result = result && verify(i, depthValue, depthValueOffset, depthValueOffsetClamp);
418         }
419
420         // Cleanup
421         gl.disableVertexAttribArray(0);
422         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
423
424         gl.deleteVertexArrays(1, &arrayBuffer);
425         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
426
427         gl.deleteVertexArrays(1, &vao);
428         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
429
430         gl.disable(GL_POLYGON_OFFSET_FILL);
431         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
432
433         if (readDepthProgram)
434                 delete readDepthProgram;
435
436         if (result)
437                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
438         else
439                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
440 }
441
442 /** Method .
443  *
444  *  @param gl   Function bindings
445  */
446 float PolygonOffsetClampValueTestCaseBase::readDepthValue(const glw::Functions& gl, const GLuint readDepthProgramId)
447 {
448         GLfloat depthValue = 0.0f;
449
450         if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
451         {
452                 gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthValue);
453                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
454         }
455         // OpenGL ES does not support reading pixels directly from depth buffer
456         else
457         {
458                 // Bind framebuffer for readback
459                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback);
460                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
461
462                 gl.disable(GL_DEPTH_TEST);
463                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
464
465                 gl.useProgram(readDepthProgramId);
466                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
467
468                 gl.activeTexture(GL_TEXTURE0);
469                 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
470                 gl.bindTexture(GL_TEXTURE_2D, m_depthBuf);
471                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
472                 gl.uniform1i(0, 0);
473                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
474
475                 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
476                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays");
477
478                 GLubyte pixels[4];
479                 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
480                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
481
482                 gl.enable(GL_DEPTH_TEST);
483                 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable");
484
485                 // Convert read depth value to GLfloat normalized
486                 depthValue = (GLfloat)(pixels[0] + pixels[1] * 256) / 0xFFFF;
487
488                 // Bind framebuffer for drawing
489                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
490                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
491         }
492
493         return depthValue;
494 }
495
496 /** Constructor.
497 *
498 *  @param context Rendering context
499 */
500 PolygonOffsetClampMinMaxTestCase::PolygonOffsetClampMinMaxTestCase(deqp::Context& context)
501         : PolygonOffsetClampValueTestCaseBase(
502                   context, "PolygonOffsetClampMinMax",
503                   "Verifies if polygon offset clamp works as expected for non-zero, finite clamp values")
504 {
505 }
506
507 /** Initialization method that fills polygonOffset* testing values
508  */
509 void PolygonOffsetClampMinMaxTestCase::init()
510 {
511         PolygonOffsetClampValueTestCaseBase::init();
512
513         m_testValues.clear();
514         m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, -0.0001f)); // Min offset case
515         m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, 0.0001f));   // Max offset case
516 }
517
518 /** Verification method that determines if depth values are as expected
519  *
520  *  @param caseNo           Case iteration number
521  *  @param depth            Reference depth value
522  *  @param offsetDepth      Case iteration number
523  *  @param offsetClampDepth Case iteration number
524  */
525 bool PolygonOffsetClampMinMaxTestCase::verify(GLuint caseNo, GLfloat depth, GLfloat offsetDepth,
526                                                                                           GLfloat offsetClampDepth)
527 {
528         // Min offset case
529         if (caseNo == 0)
530         {
531                 if (depth <= offsetDepth || depth <= offsetClampDepth || offsetDepth >= offsetClampDepth)
532                 {
533                         m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MIN offset test.\n"
534                                                            << "Expected result: "
535                                                            << "refDepth[" << depth << "] > "
536                                                            << "offsetClampDepth[" << offsetClampDepth << "] > "
537                                                            << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage;
538
539                         return false;
540                 }
541         }
542         // Max offset case
543         else if (caseNo == 1)
544         {
545                 if (depth >= offsetDepth || depth >= offsetClampDepth || offsetDepth <= offsetClampDepth)
546                 {
547                         m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MAX offset test.\n"
548                                                            << "Expected result: "
549                                                            << "refDepth[" << depth << "] < "
550                                                            << "offsetClampDepth[" << offsetClampDepth << "] < "
551                                                            << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage;
552
553                         return false;
554                 }
555         }
556         // Undefined case
557         else
558                 return false;
559
560         return true;
561 }
562
563 /** Constructor.
564 *
565 *  @param context Rendering context
566 */
567 PolygonOffsetClampZeroInfinityTestCase::PolygonOffsetClampZeroInfinityTestCase(deqp::Context& context)
568         : PolygonOffsetClampValueTestCaseBase(
569                   context, "PolygonOffsetClampZeroInfinity",
570                   "Verifies if polygon offset clamp works as expected for zero and infinite clamp values")
571 {
572 }
573
574 /** Initialization method that fills polygonOffset* testing values
575  */
576 void PolygonOffsetClampZeroInfinityTestCase::init()
577 {
578         PolygonOffsetClampValueTestCaseBase::init();
579
580         m_testValues.clear();
581         m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, 0.0f));          // Min offset, zero clamp case
582         m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, -INFINITY)); // Min Offset, infinity clamp case
583         m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, 0.0f));           // Max offset, zero clamp case
584         m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, INFINITY));   // Max Offset, infinity clamp case
585 }
586
587 bool PolygonOffsetClampZeroInfinityTestCase::verify(GLuint caseNo, GLfloat depth, GLfloat offsetDepth,
588                                                                                                         GLfloat offsetClampDepth)
589 {
590         DE_UNREF(caseNo);
591
592         if (depth == offsetDepth || depth == offsetClampDepth || offsetDepth != offsetClampDepth)
593         {
594                 m_testCtx.getLog() << tcu::TestLog::Message
595                                                    << "PolygonOffsetClampEXT failed at Zero/Infinity offset clamp test.\n"
596                                                    << "Expected result: "
597                                                    << "refDepth[" << depth << "] != "
598                                                    << "(offsetClampDepth[" << offsetClampDepth << "] == "
599                                                    << "offsetDepth[" << offsetDepth << "])" << tcu::TestLog::EndMessage;
600
601                 return false;
602         }
603
604         return true;
605 }
606
607 /** Constructor.
608 *
609 *  @param context Rendering context.
610 */
611 PolygonOffsetClamp::PolygonOffsetClamp(deqp::Context& context)
612         : TestCaseGroup(context, "polygon_offset_clamp",
613                                         "Verify conformance of CTS_EXT_polygon_offset_clamp implementation")
614 {
615 }
616
617 /** Initializes the test group contents. */
618 void PolygonOffsetClamp::init()
619 {
620         addChild(new PolygonOffsetClampAvailabilityTestCase(m_context));
621         addChild(new PolygonOffsetClampMinMaxTestCase(m_context));
622         addChild(new PolygonOffsetClampZeroInfinityTestCase(m_context));
623 }
624 } /* glcts namespace */