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