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