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 33using namespace glw; 34using namespace glu; 35 36namespace glcts 37{ 38 39const char* poc_shader_version_450core = "#version 450 core\n\n"; 40const char* poc_shader_version_310es = "#version 310 es\n\n"; 41 42const 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 49const 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 56const 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 66const 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*/ 87PolygonOffsetClampTestCaseBase::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 97tcu::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*/ 114PolygonOffsetClampAvailabilityTestCase::PolygonOffsetClampAvailabilityTestCase(deqp::Context& context) 115 : PolygonOffsetClampTestCaseBase(context, "PolygonOffsetClampAvailability", 116 "Verifies if queries for GL_EXT_polygon_offset_clamp extension works properly") 117{ 118} 119 120void 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*/ 161PolygonOffsetClampValueTestCaseBase::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 */ 174void 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 */ 235void 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 */ 262void 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 */ 453float PolygonOffsetClampValueTestCaseBase::readDepthValue(const glw::Functions& gl, const GLuint readDepthProgramId, const GLuint testProgramId) 454{ 455 GLfloat depthValue = 0.0f; 456 457 if (glu::isContextTypeGLCore(m_context.getRenderContext().getType())) 458 { 459 gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthValue); 460 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 461 } 462 // OpenGL ES does not support reading pixels directly from depth buffer 463 else 464 { 465 // Bind framebuffer for readback 466 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboReadback); 467 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); 468 469 gl.disable(GL_DEPTH_TEST); 470 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable"); 471 472 gl.useProgram(readDepthProgramId); 473 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 474 475 gl.activeTexture(GL_TEXTURE0); 476 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture"); 477 gl.bindTexture(GL_TEXTURE_2D, m_depthBuf); 478 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture"); 479 gl.uniform1i(0, 0); 480 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); 481 482 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 483 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays"); 484 485 GLubyte pixels[4]; 486 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 487 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 488 489 gl.enable(GL_DEPTH_TEST); 490 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable"); 491 492 // Convert read depth value to GLfloat normalized 493 depthValue = (GLfloat)(pixels[0] + pixels[1] * 256 + pixels[2] * 65536) / 0xFFFFFF; 494 495 // Bind framebuffer for drawing 496 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); 497 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); 498 499 gl.useProgram(testProgramId); 500 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); 501 } 502 503 return depthValue; 504} 505 506/** Constructor. 507* 508* @param context Rendering context 509*/ 510PolygonOffsetClampMinMaxTestCase::PolygonOffsetClampMinMaxTestCase(deqp::Context& context) 511 : PolygonOffsetClampValueTestCaseBase( 512 context, "PolygonOffsetClampMinMax", 513 "Verifies if polygon offset clamp works as expected for non-zero, finite clamp values") 514{ 515} 516 517/** Initialization method that fills polygonOffset* testing values 518 */ 519void PolygonOffsetClampMinMaxTestCase::init() 520{ 521 PolygonOffsetClampValueTestCaseBase::init(); 522 523 m_testValues.clear(); 524 m_testValues.push_back(PolygonOffsetClampValues(0.0f, -5000.0f, -0.0001f)); // Min offset case 525 m_testValues.push_back(PolygonOffsetClampValues(0.0f, 5000.0f, 0.0001f)); // Max offset case 526} 527 528/** Verification method that determines if depth values are as expected 529 * 530 * @param caseNo Case iteration number 531 * @param depth Reference depth value 532 * @param offsetDepth Case iteration number 533 * @param offsetClampDepth Case iteration number 534 */ 535bool PolygonOffsetClampMinMaxTestCase::verify(GLuint caseNo, GLfloat depth, GLfloat offsetDepth, 536 GLfloat offsetClampDepth) 537{ 538 // Min offset case 539 if (caseNo == 0) 540 { 541 if (depth <= offsetDepth || depth <= offsetClampDepth || offsetDepth >= offsetClampDepth) 542 { 543 m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MIN offset test.\n" 544 << "Expected result: " 545 << "refDepth[" << depth << "] > " 546 << "offsetClampDepth[" << offsetClampDepth << "] > " 547 << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage; 548 549 return false; 550 } 551 } 552 // Max offset case 553 else if (caseNo == 1) 554 { 555 if (depth >= offsetDepth || depth >= offsetClampDepth || offsetDepth <= offsetClampDepth) 556 { 557 m_testCtx.getLog() << tcu::TestLog::Message << "PolygonOffsetClampEXT failed at MAX offset test.\n" 558 << "Expected result: " 559 << "refDepth[" << depth << "] < " 560 << "offsetClampDepth[" << offsetClampDepth << "] < " 561 << "offsetDepth[" << offsetDepth << "]" << tcu::TestLog::EndMessage; 562 563 return false; 564 } 565 } 566 // Undefined case 567 else 568 return false; 569 570 return true; 571} 572 573/** Constructor. 574* 575* @param context Rendering context 576*/ 577PolygonOffsetClampZeroInfinityTestCase::PolygonOffsetClampZeroInfinityTestCase(deqp::Context& context) 578 : PolygonOffsetClampValueTestCaseBase( 579 context, "PolygonOffsetClampZeroInfinity", 580 "Verifies if polygon offset clamp works as expected for zero and infinite clamp values") 581{ 582} 583 584/** Initialization method that fills polygonOffset* testing values 585 */ 586void PolygonOffsetClampZeroInfinityTestCase::init() 587{ 588 PolygonOffsetClampValueTestCaseBase::init(); 589 590 m_testValues.clear(); 591 m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, 0.0f)); // Min offset, zero clamp case 592 m_testValues.push_back(PolygonOffsetClampValues(0.0f, -1000.0f, -INFINITY)); // Min Offset, infinity clamp case 593 m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, 0.0f)); // Max offset, zero clamp case 594 m_testValues.push_back(PolygonOffsetClampValues(0.0f, 1000.0f, INFINITY)); // Max Offset, infinity clamp case 595} 596 597bool PolygonOffsetClampZeroInfinityTestCase::verify(GLuint caseNo, GLfloat depth, GLfloat offsetDepth, 598 GLfloat offsetClampDepth) 599{ 600 DE_UNREF(caseNo); 601 602 if (depth == offsetDepth || depth == offsetClampDepth || offsetDepth != offsetClampDepth) 603 { 604 m_testCtx.getLog() << tcu::TestLog::Message 605 << "PolygonOffsetClampEXT failed at Zero/Infinity offset clamp test.\n" 606 << "Expected result: " 607 << "refDepth[" << depth << "] != " 608 << "(offsetClampDepth[" << offsetClampDepth << "] == " 609 << "offsetDepth[" << offsetDepth << "])" << tcu::TestLog::EndMessage; 610 611 return false; 612 } 613 614 return true; 615} 616 617/** Constructor. 618* 619* @param context Rendering context. 620*/ 621PolygonOffsetClamp::PolygonOffsetClamp(deqp::Context& context) 622 : TestCaseGroup(context, "polygon_offset_clamp", 623 "Verify conformance of CTS_EXT_polygon_offset_clamp implementation") 624{ 625} 626 627/** Initializes the test group contents. */ 628void PolygonOffsetClamp::init() 629{ 630 addChild(new PolygonOffsetClampAvailabilityTestCase(m_context)); 631 addChild(new PolygonOffsetClampMinMaxTestCase(m_context)); 632 addChild(new PolygonOffsetClampZeroInfinityTestCase(m_context)); 633} 634} /* glcts namespace */ 635