1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2017 The Android Open Source Project 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 21 * \brief Texture format tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fSRGBDecodeTests.hpp" 25 #include "gluContextInfo.hpp" 26 #include "gluCallLogWrapper.hpp" 27 #include "gluRenderContext.hpp" 28 #include "gluTexture.hpp" 29 #include "glsTextureTestUtil.hpp" 30 #include "tcuPixelFormat.hpp" 31 #include "tcuTestContext.hpp" 32 #include "tcuRenderTarget.hpp" 33 #include "gluTextureUtil.hpp" 34 #include "tcuTextureUtil.hpp" 35 #include "glwFunctions.hpp" 36 #include "gluDefs.hpp" 37 #include "glwEnums.hpp" 38 #include "deUniquePtr.hpp" 39 #include "gluPixelTransfer.hpp" 40 #include "tcuDefs.hpp" 41 #include "tcuVectorUtil.hpp" 42 #include "gluObjectWrapper.hpp" 43 #include "gluStrUtil.hpp" 44 #include "tcuTestLog.hpp" 45 #include "deStringUtil.hpp" 46 47 namespace deqp 48 { 49 namespace gles31 50 { 51 namespace Functional 52 { 53 namespace 54 { 55 56 using glu::TextureTestUtil::TEXTURETYPE_2D; 57 58 enum SRGBDecode 59 { 60 SRGBDECODE_SKIP_DECODE = 0, 61 SRGBDECODE_DECODE, 62 SRGBDECODE_DECODE_DEFAULT 63 }; 64 65 enum ShaderOutputs 66 { 67 SHADEROUTPUTS_ONE = 1, 68 SHADEROUTPUTS_TWO, 69 }; 70 71 enum ShaderUniforms 72 { 73 SHADERUNIFORMS_ONE = 1, 74 SHADERUNIFORMS_TWO, 75 }; 76 77 enum ShaderSamplingGroup 78 { 79 SHADERSAMPLINGGROUP_TEXTURE = 0, 80 SHADERSAMPLINGGROUP_TEXEL_FETCH 81 }; 82 83 enum ShaderSamplingType 84 { 85 TEXTURESAMPLING_TEXTURE = 0, 86 TEXTURESAMPLING_TEXTURE_LOD, 87 TEXTURESAMPLING_TEXTURE_GRAD, 88 TEXTURESAMPLING_TEXTURE_OFFSET, 89 TEXTURESAMPLING_TEXTURE_PROJ, 90 TEXTURESAMPLING_TEXELFETCH, 91 TEXTURESAMPLING_TEXELFETCH_OFFSET, 92 93 // ranges required for looping mechanism in a case nodes iteration function 94 TEXTURESAMPLING_TEXTURE_START = TEXTURESAMPLING_TEXTURE, 95 TEXTURESAMPLING_TEXTURE_END = TEXTURESAMPLING_TEXTURE_PROJ + 1, 96 TEXTURESAMPLING_TEXELFETCH_START = TEXTURESAMPLING_TEXELFETCH, 97 TEXTURESAMPLING_TEXELFETCH_END = TEXTURESAMPLING_TEXELFETCH_OFFSET + 1 98 }; 99 100 enum FunctionParameters 101 { 102 FUNCTIONPARAMETERS_ONE = 1, 103 FUNCTIONPARAMETERS_TWO 104 }; 105 106 enum Blending 107 { 108 BLENDING_REQUIRED = 0, 109 BLENDING_NOT_REQUIRED 110 }; 111 112 enum Toggling 113 { 114 TOGGLING_REQUIRED = 0, 115 TOGGLING_NOT_REQUIRED 116 }; 117 118 tcu::Vec4 getColorReferenceLinear (void) 119 { 120 return tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f); 121 } 122 123 tcu::Vec4 getColorReferenceSRGB (void) 124 { 125 return tcu::linearToSRGB(tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f)); 126 } 127 128 tcu::Vec4 getColorGreenPass (void) 129 { 130 return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f); 131 } 132 133 namespace TestDimensions 134 { 135 const int WIDTH = 128; 136 const int HEIGHT = 128; 137 } // global test texture dimensions 138 139 namespace TestSamplingPositions 140 { 141 const int X_POS = 0; 142 const int Y_POS = 0; 143 } // global test sampling positions 144 145 const char* getFunctionDefinitionSRGBToLinearCheck (void) 146 { 147 static const char* functionDefinition = 148 "mediump vec4 srgbToLinearCheck(in mediump vec4 texelSRGBA, in mediump vec4 texelLinear) \n" 149 "{ \n" 150 " const int NUM_CHANNELS = 4;" 151 " mediump vec4 texelSRGBAConverted; \n" 152 " mediump vec4 epsilonErr = vec4(0.005); \n" 153 " mediump vec4 testResult; \n" 154 " for (int idx = 0; idx < NUM_CHANNELS; idx++) \n" 155 " { \n" 156 " texelSRGBAConverted[idx] = pow( (texelSRGBA[idx] + 0.055) / 1.055, 1.0 / 0.4116); \n" 157 " } \n" 158 " if ( all(lessThan(abs(texelSRGBAConverted - texelLinear), epsilonErr)) || all(equal(texelSRGBAConverted, texelLinear)) ) \n" 159 " { \n" 160 " return testResult = vec4(0.0, 1.0, 0.0, 1.0); \n" 161 " } \n" 162 " else \n" 163 " { \n" 164 " return testResult = vec4(1.0, 0.0, 0.0, 1.0); \n" 165 " } \n" 166 "} \n"; 167 168 return functionDefinition; 169 } 170 171 const char* getFunctionDefinitionEqualCheck (void) 172 { 173 static const char* functionDefinition = 174 "mediump vec4 colorsEqualCheck(in mediump vec4 colorA, in mediump vec4 colorB) \n" 175 "{ \n" 176 " mediump vec4 epsilonErr = vec4(0.005); \n" 177 " mediump vec4 testResult; \n" 178 " if ( all(lessThan(abs(colorA - colorB), epsilonErr)) || all(equal(colorA, colorB)) ) \n" 179 " { \n" 180 " return testResult = vec4(0.0, 1.0, 0.0, 1.0); \n" 181 " } \n" 182 " else \n" 183 " { \n" 184 " return testResult = vec4(1.0, 0.0, 0.0, 1.0); \n" 185 " } \n" 186 "} \n"; 187 188 return functionDefinition; 189 } 190 191 namespace EpsilonError 192 { 193 const float CPU = 0.005f; 194 } 195 196 struct TestGroupConfig 197 { 198 TestGroupConfig (const char* groupName, const char* groupDescription, const tcu::TextureFormat groupInternalFormat) 199 : name (groupName) 200 , description (groupDescription) 201 , internalFormat (groupInternalFormat) {} 202 203 ~TestGroupConfig (void) {}; 204 205 const char* name; 206 const char* description; 207 const tcu::TextureFormat internalFormat; 208 }; 209 210 struct UniformData 211 { 212 UniformData (glw::GLuint uniformLocation, const std::string& uniformName) 213 : location (uniformLocation) 214 , name (uniformName) 215 , toggleDecode (false) {} 216 217 ~UniformData (void) {} 218 219 glw::GLuint location; 220 std::string name; 221 bool toggleDecode; 222 }; 223 224 struct UniformToToggle 225 { 226 UniformToToggle (const int uniformProgramIdx, const std::string& uniformName) 227 : programIdx (uniformProgramIdx) 228 , name (uniformName) {} 229 230 ~UniformToToggle (void) {} 231 232 int programIdx; 233 std::string name; 234 }; 235 236 struct ComparisonFunction 237 { 238 ComparisonFunction (const std::string& funcName, const FunctionParameters funcParameters, const std::string& funcImplementation) 239 : name (funcName) 240 , parameters (funcParameters) 241 , implementation (funcImplementation) {} 242 243 ~ComparisonFunction (void) {} 244 245 std::string name; 246 FunctionParameters parameters; 247 std::string implementation; 248 }; 249 250 struct FragmentShaderParameters 251 { 252 FragmentShaderParameters (const ShaderOutputs outputTotal, 253 const ShaderUniforms uniformTotal, 254 ComparisonFunction* comparisonFunction, 255 Blending blendRequired, 256 Toggling toggleRequired); 257 258 ~FragmentShaderParameters (void); 259 260 ShaderOutputs outputTotal; 261 ShaderUniforms uniformTotal; 262 ShaderSamplingType samplingType; 263 std::string functionName; 264 FunctionParameters functionParameters; 265 std::string functionImplementation; 266 bool hasFunction; 267 Blending blendRequired; 268 Toggling toggleRequired; 269 std::vector<std::string> uniformsToToggle; 270 }; 271 272 FragmentShaderParameters::FragmentShaderParameters (const ShaderOutputs paramsOutputTotal, 273 const ShaderUniforms paramsUniformTotal, 274 ComparisonFunction* paramsComparisonFunction, 275 Blending paramsBlendRequired, 276 Toggling paramsToggleRequired) 277 : outputTotal (paramsOutputTotal) 278 , uniformTotal (paramsUniformTotal) 279 , blendRequired (paramsBlendRequired) 280 , toggleRequired (paramsToggleRequired) 281 { 282 if (paramsComparisonFunction != DE_NULL) 283 { 284 functionName = paramsComparisonFunction->name; 285 functionParameters = paramsComparisonFunction->parameters; 286 functionImplementation = paramsComparisonFunction->implementation; 287 288 hasFunction = true; 289 } 290 else 291 { 292 hasFunction = false; 293 } 294 } 295 296 FragmentShaderParameters::~FragmentShaderParameters (void) 297 { 298 } 299 300 class SRGBTestSampler 301 { 302 public: 303 SRGBTestSampler (Context& context, 304 const tcu::Sampler::WrapMode wrapS, 305 const tcu::Sampler::WrapMode wrapT, 306 const tcu::Sampler::FilterMode minFilter, 307 const tcu::Sampler::FilterMode magFilter, 308 const SRGBDecode decoding); 309 ~SRGBTestSampler (void); 310 311 void setDecode (const SRGBDecode decoding); 312 void setTextureUnit (const deUint32 textureUnit); 313 void setIsActive (const bool isActive); 314 315 bool getIsActive (void) const; 316 317 void bindToTexture (void); 318 319 private: 320 const glw::Functions* m_gl; 321 deUint32 m_samplerHandle; 322 tcu::Sampler::WrapMode m_wrapS; 323 tcu::Sampler::WrapMode m_wrapT; 324 tcu::Sampler::FilterMode m_minFilter; 325 tcu::Sampler::FilterMode m_magFilter; 326 SRGBDecode m_decoding; 327 deUint32 m_textureUnit; 328 bool m_isActive; 329 }; 330 331 SRGBTestSampler::SRGBTestSampler (Context& context, 332 const tcu::Sampler::WrapMode wrapS, 333 const tcu::Sampler::WrapMode wrapT, 334 const tcu::Sampler::FilterMode minFilter, 335 const tcu::Sampler::FilterMode magFilter, 336 const SRGBDecode decoding) 337 : m_gl (&context.getRenderContext().getFunctions()) 338 , m_wrapS (wrapS) 339 , m_wrapT (wrapT) 340 , m_minFilter (minFilter) 341 , m_magFilter (magFilter) 342 , m_isActive (false) 343 { 344 m_gl->genSamplers(1, &m_samplerHandle); 345 346 m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS)); 347 m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT)); 348 m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter)); 349 m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter)); 350 351 this->setDecode(decoding); 352 } 353 354 SRGBTestSampler::~SRGBTestSampler (void) 355 { 356 m_gl->deleteSamplers(1, &m_samplerHandle); 357 } 358 359 void SRGBTestSampler::setDecode (const SRGBDecode decoding) 360 { 361 if (decoding == SRGBDECODE_SKIP_DECODE) 362 { 363 m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); 364 GLU_EXPECT_NO_ERROR(m_gl->getError(), "samplerParameteri(m_samplerID, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)"); 365 } 366 else if (decoding == SRGBDECODE_DECODE) 367 { 368 m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); 369 GLU_EXPECT_NO_ERROR(m_gl->getError(), "samplerParameteri(m_samplerID, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)"); 370 } 371 else 372 { 373 DE_FATAL("sRGB texture sampler must have either GL_SKIP_DECODE_EXT or GL_DECODE_EXT settings"); 374 } 375 376 m_decoding = decoding; 377 } 378 379 void SRGBTestSampler::setTextureUnit (const deUint32 textureUnit) 380 { 381 m_textureUnit = textureUnit; 382 } 383 384 void SRGBTestSampler::setIsActive (const bool isActive) 385 { 386 m_isActive = isActive; 387 } 388 389 bool SRGBTestSampler::getIsActive (void) const 390 { 391 return m_isActive; 392 } 393 394 void SRGBTestSampler::bindToTexture (void) 395 { 396 m_gl->bindSampler(m_textureUnit, m_samplerHandle); 397 } 398 399 class SRGBTestTexture 400 { 401 public: 402 SRGBTestTexture (Context& context, 403 const glu::TextureTestUtil::TextureType targetType, 404 const tcu::TextureFormat internalFormat, 405 const int width, 406 const int height, 407 const tcu::Vec4 color, 408 const tcu::Sampler::WrapMode wrapS, 409 const tcu::Sampler::WrapMode wrapT, 410 const tcu::Sampler::FilterMode minFilter, 411 const tcu::Sampler::FilterMode magFilter, 412 const SRGBDecode decoding); 413 ~SRGBTestTexture (void); 414 415 void setParameters (void); 416 void setDecode (const SRGBDecode decoding); 417 void setHasSampler (const bool hasSampler); 418 419 deUint32 getHandle (void) const; 420 deUint32 getGLTargetType (void) const; 421 SRGBDecode getDecode (void) const; 422 423 void upload (void); 424 425 private: 426 void setColor (void); 427 428 Context& m_context; 429 glu::Texture2D m_source; 430 glu::TextureTestUtil::TextureType m_targetType; 431 const tcu::TextureFormat m_internalFormat; 432 const int m_width; 433 const int m_height; 434 tcu::Vec4 m_color; 435 tcu::Sampler::WrapMode m_wrapS; 436 tcu::Sampler::WrapMode m_wrapT; 437 tcu::Sampler::FilterMode m_minFilter; 438 tcu::Sampler::FilterMode m_magFilter; 439 SRGBDecode m_decoding; 440 bool m_hasSampler; 441 }; 442 443 SRGBTestTexture::SRGBTestTexture (Context& context, 444 const glu::TextureTestUtil::TextureType targetType, 445 const tcu::TextureFormat internalFormat, 446 const int width, 447 const int height, 448 const tcu::Vec4 color, 449 const tcu::Sampler::WrapMode wrapS, 450 const tcu::Sampler::WrapMode wrapT, 451 const tcu::Sampler::FilterMode minFilter, 452 const tcu::Sampler::FilterMode magFilter, 453 SRGBDecode decoding) 454 : m_context (context) 455 , m_source (context.getRenderContext(), glu::getInternalFormat(internalFormat), width, height) 456 , m_targetType (targetType) 457 , m_internalFormat (internalFormat) 458 , m_width (width) 459 , m_height (height) 460 , m_color (color) 461 , m_wrapS (wrapS) 462 , m_wrapT (wrapT) 463 , m_minFilter (minFilter) 464 , m_magFilter (magFilter) 465 , m_decoding (decoding) 466 , m_hasSampler (false) 467 { 468 this->setColor(); 469 } 470 471 SRGBTestTexture::~SRGBTestTexture (void) 472 { 473 } 474 475 void SRGBTestTexture::setParameters (void) 476 { 477 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 478 479 gl.bindTexture(this->getGLTargetType(), this->getHandle()); 480 481 gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS)); 482 gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT)); 483 gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter)); 484 gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter)); 485 486 gl.bindTexture(this->getGLTargetType(), 0); 487 488 setDecode(m_decoding); 489 } 490 491 void SRGBTestTexture::setDecode (const SRGBDecode decoding) 492 { 493 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 494 495 gl.bindTexture(this->getGLTargetType(), this->getHandle()); 496 497 switch (decoding) 498 { 499 case SRGBDECODE_SKIP_DECODE: 500 { 501 gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); 502 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)"); 503 break; 504 } 505 case SRGBDECODE_DECODE: 506 { 507 gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); 508 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)"); 509 break; 510 } 511 case SRGBDECODE_DECODE_DEFAULT: 512 { 513 // do not use srgb decode options. Set to default 514 break; 515 } 516 default: 517 DE_FATAL("Error: Decoding option not recognised"); 518 } 519 520 gl.bindTexture(this->getGLTargetType(), 0); 521 522 m_decoding = decoding; 523 } 524 525 void SRGBTestTexture::setHasSampler (const bool hasSampler) 526 { 527 m_hasSampler = hasSampler; 528 } 529 530 deUint32 SRGBTestTexture::getHandle (void) const 531 { 532 return m_source.getGLTexture(); 533 } 534 535 deUint32 SRGBTestTexture::getGLTargetType (void) const 536 { 537 switch (m_targetType) 538 { 539 case TEXTURETYPE_2D: 540 { 541 return GL_TEXTURE_2D; 542 } 543 default: 544 { 545 DE_FATAL("Error: Target type not recognised"); 546 return -1; 547 } 548 } 549 } 550 551 SRGBDecode SRGBTestTexture::getDecode (void) const 552 { 553 return m_decoding; 554 } 555 556 void SRGBTestTexture::upload (void) 557 { 558 m_source.upload(); 559 } 560 561 void SRGBTestTexture::setColor (void) 562 { 563 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 564 565 gl.bindTexture(this->getGLTargetType(), this->getHandle()); 566 567 m_source.getRefTexture().allocLevel(0); 568 569 for (int py = 0; py < m_height; py++) 570 { 571 for (int px = 0; px < m_width; px++) 572 { 573 m_source.getRefTexture().getLevel(0).setPixel(m_color, px, py); 574 } 575 } 576 577 gl.bindTexture(this->getGLTargetType(), 0); 578 } 579 580 class SRGBTestProgram 581 { 582 public: 583 SRGBTestProgram (Context& context, const FragmentShaderParameters& shaderParameters); 584 ~SRGBTestProgram (void); 585 586 void setBlendRequired (bool blendRequired); 587 void setToggleRequired (bool toggleRequired); 588 void setUniformToggle (int location, bool toggleDecodeValue); 589 590 const std::vector<UniformData>& getUniformDataList (void) const; 591 int getUniformLocation (const std::string& name); 592 deUint32 getHandle (void) const; 593 bool getBlendRequired (void) const; 594 595 private: 596 std::string genFunctionCall (ShaderSamplingType samplingType, const int uniformIdx); 597 void genFragmentShader (void); 598 599 Context& m_context; 600 de::MovePtr<glu::ShaderProgram> m_program; 601 FragmentShaderParameters m_shaderFragmentParameters; 602 std::string m_shaderVertex; 603 std::string m_shaderFragment; 604 std::vector<UniformData> m_uniformDataList; 605 bool m_blendRequired; 606 bool m_toggleRequired; 607 }; 608 609 SRGBTestProgram::SRGBTestProgram (Context& context, const FragmentShaderParameters& shaderParameters) 610 : m_context (context) 611 , m_shaderFragmentParameters (shaderParameters) 612 , m_blendRequired (false) 613 , m_toggleRequired (false) 614 { 615 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 616 tcu::TestLog& log = m_context.getTestContext().getLog(); 617 glu::ShaderProgramInfo buildInfo; 618 const int totalShaderStages = 2; 619 620 // default vertex shader used in all tests 621 m_shaderVertex = "#version 310 es \n" 622 "layout (location = 0) in mediump vec3 aPosition; \n" 623 "layout (location = 1) in mediump vec2 aTexCoord; \n" 624 "out mediump vec2 vs_aTexCoord; \n" 625 "void main () \n" 626 "{ \n" 627 " gl_Position = vec4(aPosition, 1.0); \n" 628 " vs_aTexCoord = aTexCoord; \n" 629 "} \n"; 630 631 this->genFragmentShader(); 632 633 m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(m_shaderVertex, m_shaderFragment))); 634 635 if (!m_program->isOk()) 636 { 637 TCU_FAIL("Failed to compile shaders and link program"); 638 } 639 640 glw::GLint activeUniforms, maxLen; 641 glw::GLint size, location; 642 glw::GLenum type; 643 644 gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen); 645 gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORMS, &activeUniforms); 646 647 std::vector<glw::GLchar> uniformName(static_cast<int>(maxLen)); 648 for (int idx = 0; idx < activeUniforms; idx++) 649 { 650 gl.getActiveUniform(this->getHandle(), idx, maxLen, NULL, &size, &type, &uniformName[0]); 651 location = gl.getUniformLocation(this->getHandle(), &uniformName[0]); 652 653 UniformData uniformData(location, std::string(&uniformName[0], strlen(&uniformName[0]))); 654 m_uniformDataList.push_back(uniformData); 655 } 656 657 // log shader program info. Only vertex and fragment shaders included 658 buildInfo.program = m_program->getProgramInfo(); 659 for (int shaderIdx = 0; shaderIdx < totalShaderStages; shaderIdx++) 660 { 661 glu::ShaderInfo shaderInfo = m_program->getShaderInfo(static_cast<glu::ShaderType>(static_cast<int>(glu::SHADERTYPE_VERTEX) + static_cast<int>(shaderIdx)), 0); 662 buildInfo.shaders.push_back(shaderInfo); 663 } 664 665 log << buildInfo; 666 } 667 668 SRGBTestProgram::~SRGBTestProgram (void) 669 { 670 m_program = de::MovePtr<glu::ShaderProgram>(DE_NULL); 671 } 672 673 void SRGBTestProgram::setBlendRequired (bool blendRequired) 674 { 675 m_blendRequired = blendRequired; 676 } 677 678 void SRGBTestProgram::setToggleRequired (bool toggleRequired) 679 { 680 m_toggleRequired = toggleRequired; 681 } 682 683 void SRGBTestProgram::setUniformToggle (int location, bool toggleDecodeValue) 684 { 685 if ( (m_uniformDataList.empty() == false) && (location >= 0) && (location <= (int)m_uniformDataList.size()) ) 686 { 687 m_uniformDataList[location].toggleDecode = toggleDecodeValue; 688 } 689 else 690 { 691 TCU_THROW(TestError, "Error: Uniform location not found. glGetActiveUniforms returned uniforms incorrectly "); 692 } 693 } 694 695 const std::vector<UniformData>& SRGBTestProgram::getUniformDataList (void) const 696 { 697 return m_uniformDataList; 698 } 699 700 int SRGBTestProgram::getUniformLocation (const std::string& name) 701 { 702 for (std::size_t idx = 0; idx < m_uniformDataList.size(); idx++) 703 { 704 if (m_uniformDataList[idx].name == name) 705 { 706 return m_uniformDataList[idx].location; 707 } 708 } 709 710 TCU_THROW(TestError, "Error: If name correctly requested then glGetActiveUniforms() returned active uniform data incorrectly"); 711 return -1; 712 } 713 714 glw::GLuint SRGBTestProgram::getHandle (void) const 715 { 716 return m_program->getProgram(); 717 } 718 719 bool SRGBTestProgram::getBlendRequired (void) const 720 { 721 return m_blendRequired; 722 } 723 724 std::string SRGBTestProgram::genFunctionCall (ShaderSamplingType samplingType, const int uniformIdx) 725 { 726 std::ostringstream functionCall; 727 728 functionCall << " mediump vec4 texelColor" << uniformIdx << " = "; 729 730 switch (samplingType) 731 { 732 case TEXTURESAMPLING_TEXTURE: 733 { 734 functionCall << "texture(uTexture" << uniformIdx << ", vs_aTexCoord); \n"; 735 break; 736 } 737 case TEXTURESAMPLING_TEXTURE_LOD: 738 { 739 functionCall << "textureLod(uTexture" << uniformIdx << ", vs_aTexCoord, 0.0); \n"; 740 break; 741 } 742 case TEXTURESAMPLING_TEXTURE_GRAD: 743 { 744 functionCall << "textureGrad(uTexture" << uniformIdx << ", vs_aTexCoord, vec2(0.0, 0.0), vec2(0.0, 0.0)); \n"; 745 break; 746 } 747 case TEXTURESAMPLING_TEXTURE_OFFSET: 748 { 749 functionCall << "textureOffset(uTexture" << uniformIdx << ", vs_aTexCoord, ivec2(0.0, 0.0)); \n"; 750 break; 751 } 752 case TEXTURESAMPLING_TEXTURE_PROJ: 753 { 754 functionCall << "textureProj(uTexture" << uniformIdx << ", vec3(vs_aTexCoord, 1.0)); \n"; 755 break; 756 } 757 case TEXTURESAMPLING_TEXELFETCH: 758 { 759 functionCall << "texelFetch(uTexture" << uniformIdx << ", ivec2(vs_aTexCoord), 0); \n"; 760 break; 761 } 762 case TEXTURESAMPLING_TEXELFETCH_OFFSET: 763 { 764 functionCall << "texelFetchOffset(uTexture" << uniformIdx << ", ivec2(vs_aTexCoord), 0, ivec2(0.0, 0.0)); \n"; 765 break; 766 } 767 default: 768 { 769 DE_FATAL("Error: Sampling type not recognised"); 770 } 771 } 772 773 return functionCall.str(); 774 } 775 776 void SRGBTestProgram::genFragmentShader (void) 777 { 778 std::ostringstream source; 779 std::ostringstream sampleTexture; 780 std::ostringstream functionParameters; 781 std::ostringstream shaderOutputs; 782 783 // if comparison function is present resulting shader requires precisely one output 784 DE_ASSERT( !(m_shaderFragmentParameters.hasFunction && (static_cast<int>(m_shaderFragmentParameters.outputTotal) != static_cast<int>(SHADEROUTPUTS_ONE))) ); 785 786 // function parameters must equal the number of uniforms i.e. textures passed into the function 787 DE_ASSERT( !(m_shaderFragmentParameters.hasFunction && (static_cast<int>(m_shaderFragmentParameters.uniformTotal) != static_cast<int>(m_shaderFragmentParameters.functionParameters))) ); 788 789 // fragment shader cannot contain more outputs than the number of texture uniforms 790 DE_ASSERT( !(static_cast<int>(m_shaderFragmentParameters.outputTotal) > static_cast<int>(m_shaderFragmentParameters.uniformTotal)) ) ; 791 792 source << "#version 310 es \n" 793 << "in mediump vec2 vs_aTexCoord; \n"; 794 795 for (int output = 0; output < m_shaderFragmentParameters.outputTotal; output++) 796 { 797 source << "layout (location = " << output << ") out mediump vec4 fs_aColor" << output << "; \n"; 798 } 799 800 for (int uniform = 0; uniform < m_shaderFragmentParameters.uniformTotal; uniform++) 801 { 802 source << "uniform sampler2D uTexture" << uniform << "; \n"; 803 } 804 805 if (m_shaderFragmentParameters.hasFunction == true) 806 { 807 source << m_shaderFragmentParameters.functionImplementation; 808 } 809 810 source << "void main () \n" 811 << "{ \n"; 812 813 for (int uniformIdx = 0; uniformIdx < m_shaderFragmentParameters.uniformTotal; uniformIdx++) 814 { 815 source << this->genFunctionCall(m_shaderFragmentParameters.samplingType, uniformIdx); 816 } 817 818 if (m_shaderFragmentParameters.hasFunction == true) 819 { 820 switch ( static_cast<FunctionParameters>(m_shaderFragmentParameters.functionParameters) ) 821 { 822 case FUNCTIONPARAMETERS_ONE: 823 { 824 functionParameters << "(texelColor0)"; 825 break; 826 } 827 case FUNCTIONPARAMETERS_TWO: 828 { 829 functionParameters << "(texelColor0, texelColor1)"; 830 break; 831 } 832 default: 833 { 834 DE_FATAL("Error: Number of comparison function parameters invalid"); 835 } 836 } 837 838 shaderOutputs << " fs_aColor0 = " << m_shaderFragmentParameters.functionName << functionParameters.str() << "; \n"; 839 } 840 else 841 { 842 for (int output = 0; output < m_shaderFragmentParameters.outputTotal; output++) 843 { 844 shaderOutputs << " fs_aColor" << output << " = texelColor" << output << "; \n"; 845 } 846 } 847 848 source << shaderOutputs.str(); 849 source << "} \n"; 850 851 m_shaderFragment = source.str(); 852 } 853 854 class SRGBTestCase : public TestCase 855 { 856 public: 857 SRGBTestCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat); 858 ~SRGBTestCase (void); 859 860 void init (void); 861 void deinit (void); 862 virtual IterateResult iterate (void); 863 864 void setSamplingGroup (const ShaderSamplingGroup samplingGroup); 865 void setSamplingLocations (const int px, const int py); 866 void setUniformToggle (const int programIdx, const std::string& uniformName, bool toggleDecode); 867 868 void addTexture (const glu::TextureTestUtil::TextureType targetType, 869 const int width, 870 const int height, 871 const tcu::Vec4 color, 872 const tcu::Sampler::WrapMode wrapS, 873 const tcu::Sampler::WrapMode wrapT, 874 const tcu::Sampler::FilterMode minFilter, 875 const tcu::Sampler::FilterMode magFilter, 876 const SRGBDecode decoding); 877 void addSampler (const tcu::Sampler::WrapMode wrapS, 878 const tcu::Sampler::WrapMode wrapT, 879 const tcu::Sampler::FilterMode minFilter, 880 const tcu::Sampler::FilterMode magFilter, 881 const SRGBDecode decoding); 882 void addShaderProgram (const FragmentShaderParameters& shaderParameters); 883 884 void genShaderPrograms (ShaderSamplingType samplingType); 885 void deleteShaderPrograms (void); 886 887 void readResultTextures (void); 888 void storeResultPixels (std::vector<tcu::Vec4>& resultPixelData); 889 890 void toggleDecode (const std::vector<UniformData>& uniformDataList); 891 void bindSamplerToTexture (const int samplerIdx, const int textureIdx, const deUint32 textureUnit); 892 void activateSampler (const int samplerIdx, const bool active); 893 void logColor (const std::string& colorLogMessage, int colorIdx, tcu::Vec4 color) const; 894 tcu::Vec4 formatReferenceColor (tcu::Vec4 referenceColor); 895 896 // render function has a default implentation. Can be overriden for special cases 897 virtual void render (void); 898 899 // following functions must be overidden to perform individual test cases 900 virtual void setupTest (void) = 0; 901 virtual bool verifyResult (void) = 0; 902 903 protected: 904 de::MovePtr<glu::Framebuffer> m_framebuffer; 905 std::vector<SRGBTestTexture*> m_textureSourceList; 906 std::vector<SRGBTestSampler*> m_samplerList; 907 std::vector<glw::GLuint> m_renderBufferList; 908 const tcu::Vec4 m_epsilonError; 909 std::vector<tcu::TextureLevel> m_textureResultList; 910 int m_resultOutputTotal; 911 tcu::TextureFormat m_resultTextureFormat; 912 glw::GLuint m_vaoID; 913 glw::GLuint m_vertexDataID; 914 std::vector<FragmentShaderParameters> m_shaderParametersList; 915 std::vector<SRGBTestProgram*> m_shaderProgramList; 916 ShaderSamplingGroup m_samplingGroup; 917 int m_px; 918 int m_py; 919 const tcu::TextureFormat m_internalFormat; 920 921 private: 922 void uploadTextures (void); 923 void initFrameBuffer (void); 924 void initVertexData (void); 925 926 SRGBTestCase (const SRGBTestCase&); 927 SRGBTestCase& operator= (const SRGBTestCase&); 928 }; 929 930 SRGBTestCase::SRGBTestCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 931 : TestCase (context, name, description) 932 , m_epsilonError (EpsilonError::CPU) 933 , m_resultTextureFormat (tcu::TextureFormat(tcu::TextureFormat::sRGBA, tcu::TextureFormat::UNORM_INT8)) 934 , m_vaoID (0) 935 , m_vertexDataID (0) 936 , m_samplingGroup (SHADERSAMPLINGGROUP_TEXTURE) 937 , m_internalFormat (internalFormat) 938 { 939 } 940 941 SRGBTestCase::~SRGBTestCase (void) 942 { 943 deinit(); 944 } 945 946 void SRGBTestCase::init (void) 947 { 948 // extension requirements for test 949 if ( (glu::getInternalFormat(m_internalFormat) == GL_SRGB8_ALPHA8) && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_decode") ) 950 { 951 throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_decode extension"); 952 } 953 954 if ( (glu::getInternalFormat(m_internalFormat) == GL_SR8_EXT) && !(m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_R8")) ) 955 { 956 throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_R8 extension"); 957 } 958 959 m_framebuffer = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext())); 960 } 961 962 void SRGBTestCase::deinit (void) 963 { 964 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 965 966 m_framebuffer = de::MovePtr<glu::Framebuffer>(DE_NULL); 967 968 for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++) 969 { 970 gl.deleteRenderbuffers(1, &m_renderBufferList[renderBufferIdx]); 971 } 972 m_renderBufferList.clear(); 973 974 for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++) 975 { 976 delete m_textureSourceList[textureSourceIdx]; 977 } 978 m_textureSourceList.clear(); 979 980 for (std::size_t samplerIdx = 0; samplerIdx < m_samplerList.size(); samplerIdx++) 981 { 982 delete m_samplerList[samplerIdx]; 983 } 984 m_samplerList.clear(); 985 986 if (m_vaoID != 0) 987 { 988 gl.deleteVertexArrays(1, &m_vaoID); 989 m_vaoID = 0; 990 } 991 992 if (m_vertexDataID != 0) 993 { 994 gl.deleteBuffers(1, &m_vertexDataID); 995 m_vertexDataID = 0; 996 } 997 } 998 999 SRGBTestCase::IterateResult SRGBTestCase::iterate (void) 1000 { 1001 bool result; 1002 int startIdx = -1; 1003 int endIdx = -1; 1004 1005 this->setupTest(); 1006 1007 if (m_samplingGroup == SHADERSAMPLINGGROUP_TEXTURE) 1008 { 1009 startIdx = static_cast<int>(TEXTURESAMPLING_TEXTURE_START); 1010 endIdx = static_cast<int>(TEXTURESAMPLING_TEXTURE_END); 1011 } 1012 else if (m_samplingGroup == SHADERSAMPLINGGROUP_TEXEL_FETCH) 1013 { 1014 startIdx = static_cast<int>(TEXTURESAMPLING_TEXELFETCH_START); 1015 endIdx = static_cast<int>(TEXTURESAMPLING_TEXELFETCH_END); 1016 } 1017 else 1018 { 1019 DE_FATAL("Error: Sampling group not defined"); 1020 } 1021 1022 this->initVertexData(); 1023 this->initFrameBuffer(); 1024 1025 // loop through all sampling types in the required sampling group, performing individual tests for each 1026 for (int samplingTypeIdx = startIdx; samplingTypeIdx < endIdx; samplingTypeIdx++) 1027 { 1028 this->genShaderPrograms(static_cast<ShaderSamplingType>(samplingTypeIdx)); 1029 this->uploadTextures(); 1030 this->render(); 1031 1032 result = this->verifyResult(); 1033 1034 this->deleteShaderPrograms(); 1035 1036 if (result == true) 1037 { 1038 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1039 } 1040 else 1041 { 1042 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed"); 1043 return STOP; 1044 } 1045 } 1046 1047 return STOP; 1048 } 1049 1050 void SRGBTestCase::setSamplingGroup (const ShaderSamplingGroup samplingGroup) 1051 { 1052 m_samplingGroup = samplingGroup; 1053 } 1054 1055 void SRGBTestCase::setSamplingLocations (const int px, const int py) 1056 { 1057 m_px = px; 1058 m_py = py; 1059 } 1060 1061 void SRGBTestCase::addTexture ( const glu::TextureTestUtil::TextureType targetType, 1062 const int width, 1063 const int height, 1064 const tcu::Vec4 color, 1065 const tcu::Sampler::WrapMode wrapS, 1066 const tcu::Sampler::WrapMode wrapT, 1067 const tcu::Sampler::FilterMode minFilter, 1068 const tcu::Sampler::FilterMode magFilter, 1069 const SRGBDecode decoding) 1070 { 1071 SRGBTestTexture* texture = new SRGBTestTexture(m_context, targetType, m_internalFormat, width, height, color, wrapS, wrapT, minFilter, magFilter, decoding); 1072 m_textureSourceList.push_back(texture); 1073 } 1074 1075 void SRGBTestCase::addSampler ( const tcu::Sampler::WrapMode wrapS, 1076 const tcu::Sampler::WrapMode wrapT, 1077 const tcu::Sampler::FilterMode minFilter, 1078 const tcu::Sampler::FilterMode magFilter, 1079 const SRGBDecode decoding) 1080 { 1081 SRGBTestSampler *sampler = new SRGBTestSampler(m_context, wrapS, wrapT, minFilter, magFilter, decoding); 1082 m_samplerList.push_back(sampler); 1083 } 1084 1085 void SRGBTestCase::addShaderProgram (const FragmentShaderParameters& shaderParameters) 1086 { 1087 m_shaderParametersList.push_back(shaderParameters); 1088 m_resultOutputTotal = shaderParameters.outputTotal; 1089 } 1090 1091 void SRGBTestCase::genShaderPrograms (ShaderSamplingType samplingType) 1092 { 1093 for (int shaderParamsIdx = 0; shaderParamsIdx < (int)m_shaderParametersList.size(); shaderParamsIdx++) 1094 { 1095 m_shaderParametersList[shaderParamsIdx].samplingType = samplingType; 1096 SRGBTestProgram* shaderProgram = new SRGBTestProgram(m_context, m_shaderParametersList[shaderParamsIdx]); 1097 1098 if (m_shaderParametersList[shaderParamsIdx].blendRequired == BLENDING_REQUIRED) 1099 { 1100 shaderProgram->setBlendRequired(true); 1101 } 1102 1103 if (m_shaderParametersList[shaderParamsIdx].toggleRequired == TOGGLING_REQUIRED) 1104 { 1105 shaderProgram->setToggleRequired(true); 1106 std::vector<std::string> uniformsToToggle = m_shaderParametersList[shaderParamsIdx].uniformsToToggle; 1107 1108 for (int uniformNameIdx = 0; uniformNameIdx < (int)uniformsToToggle.size(); uniformNameIdx++) 1109 { 1110 shaderProgram->setUniformToggle(shaderProgram->getUniformLocation(uniformsToToggle[uniformNameIdx]), true); 1111 } 1112 } 1113 1114 m_shaderProgramList.push_back(shaderProgram); 1115 } 1116 } 1117 1118 void SRGBTestCase::deleteShaderPrograms (void) 1119 { 1120 for (std::size_t idx = 0; idx < m_shaderProgramList.size(); idx++) 1121 { 1122 delete m_shaderProgramList[idx]; 1123 } 1124 m_shaderProgramList.clear(); 1125 } 1126 1127 void SRGBTestCase::readResultTextures (void) 1128 { 1129 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1130 int width = m_context.getRenderContext().getRenderTarget().getWidth(); 1131 int height = m_context.getRenderContext().getRenderTarget().getHeight(); 1132 1133 gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer); 1134 1135 m_textureResultList.resize(m_renderBufferList.size()); 1136 1137 for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++) 1138 { 1139 gl.readBuffer(GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx); 1140 m_textureResultList[renderBufferIdx].setStorage(m_resultTextureFormat, width, height); 1141 glu::readPixels(m_context.getRenderContext(), 0, 0, m_textureResultList[renderBufferIdx].getAccess()); 1142 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()"); 1143 } 1144 1145 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1146 } 1147 1148 void SRGBTestCase::storeResultPixels (std::vector<tcu::Vec4>& resultPixelData) 1149 { 1150 tcu::TestLog& log = m_context.getTestContext().getLog(); 1151 std::ostringstream message; 1152 int width = m_context.getRenderContext().getRenderTarget().getWidth(); 1153 int height = m_context.getRenderContext().getRenderTarget().getHeight(); 1154 1155 // ensure result sampling coordinates are within range of the result color attachment 1156 DE_ASSERT((m_px >= 0) && (m_px < width)); 1157 DE_ASSERT((m_py >= 0) && (m_py < height)); 1158 DE_UNREF(width && height); 1159 1160 for (int idx = 0; idx < (int)m_textureResultList.size(); idx++) 1161 { 1162 resultPixelData.push_back(m_textureResultList[idx].getAccess().getPixel(m_px, m_py)); 1163 this->logColor(std::string("Result color: "), idx, resultPixelData[idx]); 1164 } 1165 1166 // log error rate (threshold) 1167 message << m_epsilonError; 1168 log << tcu::TestLog::Message << std::string("Epsilon error: ") << message.str() << tcu::TestLog::EndMessage; 1169 } 1170 1171 void SRGBTestCase::toggleDecode (const std::vector<UniformData>& uniformDataList) 1172 { 1173 DE_ASSERT( uniformDataList.size() <= m_textureSourceList.size() ); 1174 1175 for (int uniformIdx = 0; uniformIdx < (int)uniformDataList.size(); uniformIdx++) 1176 { 1177 if (uniformDataList[uniformIdx].toggleDecode == true) 1178 { 1179 if (m_textureSourceList[uniformIdx]->getDecode() == SRGBDECODE_DECODE_DEFAULT) 1180 { 1181 // cannot toggle default 1182 continue; 1183 } 1184 1185 // toggle sRGB decode values (ignoring value if set to default) 1186 m_textureSourceList[uniformIdx]->setDecode((SRGBDecode)((m_textureSourceList[uniformIdx]->getDecode() + 1) % SRGBDECODE_DECODE_DEFAULT)); 1187 } 1188 } 1189 } 1190 1191 void SRGBTestCase::bindSamplerToTexture (const int samplerIdx, const int textureIdx, const deUint32 textureUnit) 1192 { 1193 deUint32 enumConversion = textureUnit - GL_TEXTURE0; 1194 m_textureSourceList[textureIdx]->setHasSampler(true); 1195 m_samplerList[samplerIdx]->setTextureUnit(enumConversion); 1196 } 1197 1198 void SRGBTestCase::activateSampler (const int samplerIdx, const bool active) 1199 { 1200 m_samplerList[samplerIdx]->setIsActive(active); 1201 } 1202 1203 void SRGBTestCase::logColor (const std::string& colorLogMessage, int colorIdx, tcu::Vec4 color) const 1204 { 1205 tcu::TestLog& log = m_context.getTestContext().getLog(); 1206 std::ostringstream message; 1207 1208 message << colorLogMessage << colorIdx << " = (" << color.x() << ", " << color.y() << ", " << color.z() << ", " << color.w() << ")"; 1209 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage; 1210 } 1211 1212 tcu::Vec4 SRGBTestCase::formatReferenceColor (tcu::Vec4 referenceColor) 1213 { 1214 switch (glu::getInternalFormat(m_internalFormat)) 1215 { 1216 case GL_SRGB8_ALPHA8: 1217 { 1218 return referenceColor; 1219 } 1220 case GL_SR8_EXT: 1221 { 1222 // zero unwanted color channels 1223 referenceColor.y() = 0; 1224 referenceColor.z() = 0; 1225 return referenceColor; 1226 } 1227 default: 1228 { 1229 DE_FATAL("Error: Internal format not recognised"); 1230 return referenceColor; 1231 } 1232 } 1233 } 1234 1235 void SRGBTestCase::render (void) 1236 { 1237 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1238 1239 // default rendering only uses one program 1240 gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer); 1241 gl.bindVertexArray(m_vaoID); 1242 1243 gl.useProgram(m_shaderProgramList[0]->getHandle()); 1244 1245 for (int textureSourceIdx = 0; textureSourceIdx < (int)m_textureSourceList.size(); textureSourceIdx++) 1246 { 1247 gl.activeTexture(GL_TEXTURE0 + (glw::GLenum)textureSourceIdx); 1248 gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), m_textureSourceList[textureSourceIdx]->getHandle()); 1249 glw::GLuint samplerUniformLocationID = gl.getUniformLocation(m_shaderProgramList[0]->getHandle(), (std::string("uTexture") + de::toString(textureSourceIdx)).c_str()); 1250 TCU_CHECK(samplerUniformLocationID != (glw::GLuint)-1); 1251 gl.uniform1i(samplerUniformLocationID, (glw::GLenum)textureSourceIdx); 1252 } 1253 1254 for (int samplerIdx = 0; samplerIdx < (int)m_samplerList.size(); samplerIdx++) 1255 { 1256 if (m_samplerList[samplerIdx]->getIsActive() == true) 1257 { 1258 m_samplerList[samplerIdx]->bindToTexture(); 1259 } 1260 } 1261 1262 gl.drawArrays(GL_TRIANGLES, 0, 6); 1263 1264 for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++) 1265 { 1266 gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), 0); 1267 } 1268 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1269 gl.bindVertexArray(0); 1270 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1271 } 1272 1273 void SRGBTestCase::uploadTextures (void) 1274 { 1275 for (std::size_t idx = 0; idx < m_textureSourceList.size(); idx++) 1276 { 1277 m_textureSourceList[idx]->upload(); 1278 m_textureSourceList[idx]->setParameters(); 1279 } 1280 } 1281 1282 void SRGBTestCase::initFrameBuffer (void) 1283 { 1284 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1285 int width = m_context.getRenderContext().getRenderTarget().getWidth(); 1286 int height = m_context.getRenderContext().getRenderTarget().getHeight(); 1287 1288 if (m_resultOutputTotal == 0) 1289 { 1290 throw std::invalid_argument("SRGBTestExecutor must have at least 1 rendered result"); 1291 } 1292 1293 gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer); 1294 1295 DE_ASSERT(m_renderBufferList.empty()); 1296 for (int outputIdx = 0; outputIdx < m_resultOutputTotal; outputIdx++) 1297 { 1298 glw::GLuint renderBuffer = -1; 1299 m_renderBufferList.push_back(renderBuffer); 1300 } 1301 1302 for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++) 1303 { 1304 gl.genRenderbuffers(1, &m_renderBufferList[renderBufferIdx]); 1305 gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderBufferList[renderBufferIdx]); 1306 gl.renderbufferStorage(GL_RENDERBUFFER, glu::getInternalFormat(m_resultTextureFormat), width, height); 1307 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx, GL_RENDERBUFFER, m_renderBufferList[renderBufferIdx]); 1308 GLU_EXPECT_NO_ERROR(gl.getError(), "Create and setup renderbuffer object"); 1309 } 1310 TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 1311 1312 std::vector<glw::GLenum> renderBufferTargets(m_renderBufferList.size()); 1313 for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++) 1314 { 1315 renderBufferTargets[renderBufferIdx] = GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx; 1316 } 1317 gl.drawBuffers((glw::GLsizei)renderBufferTargets.size(), &renderBufferTargets[0]); 1318 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer()"); 1319 1320 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1321 } 1322 1323 void SRGBTestCase::initVertexData (void) 1324 { 1325 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1326 1327 static const glw::GLfloat squareVertexData[] = 1328 { 1329 // position // texcoord 1330 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left corner 1331 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right corner 1332 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top right corner 1333 1334 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top left corner 1335 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top right corner 1336 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f // bottom left corner 1337 }; 1338 1339 DE_ASSERT(m_vaoID == 0); 1340 gl.genVertexArrays(1, &m_vaoID); 1341 gl.bindVertexArray(m_vaoID); 1342 1343 gl.genBuffers(1, &m_vertexDataID); 1344 gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexDataID); 1345 gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW); 1346 1347 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)0); 1348 gl.enableVertexAttribArray(0); 1349 gl.vertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)(3 * sizeof(GL_FLOAT))); 1350 gl.enableVertexAttribArray(1); 1351 1352 gl.bindVertexArray(0); 1353 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1354 } 1355 1356 class TextureDecodeSkippedCase : public SRGBTestCase 1357 { 1358 public: 1359 TextureDecodeSkippedCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1360 : SRGBTestCase (context, name, description, internalFormat) {} 1361 1362 ~TextureDecodeSkippedCase (void) {} 1363 1364 void setupTest (void); 1365 bool verifyResult (void); 1366 }; 1367 1368 void TextureDecodeSkippedCase::setupTest (void) 1369 { 1370 // TEST STEPS: 1371 // - create and set texture to DECODE_SKIP_EXT 1372 // - store texture on GPU 1373 // - in fragment shader, sample the texture using texture*() and render texel values to a color attachment in the FBO 1374 // - on the host, read back the pixel values into a tcu::TextureLevel 1375 // - analyse the texel values, expecting them in sRGB format i.e. linear space decoding was skipped 1376 1377 FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1378 1379 this->addTexture( TEXTURETYPE_2D, 1380 TestDimensions::WIDTH, 1381 TestDimensions::HEIGHT, 1382 getColorReferenceLinear(), 1383 tcu::Sampler::MIRRORED_REPEAT_GL, 1384 tcu::Sampler::MIRRORED_REPEAT_GL, 1385 tcu::Sampler::LINEAR, 1386 tcu::Sampler::LINEAR, 1387 SRGBDECODE_SKIP_DECODE); 1388 1389 this->addShaderProgram(shaderParameters); 1390 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1391 1392 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE); 1393 } 1394 1395 bool TextureDecodeSkippedCase::verifyResult (void) 1396 { 1397 tcu::TestLog& log = m_context.getTestContext().getLog(); 1398 const int resultColorIdx = 0; 1399 std::vector<tcu::Vec4> pixelResultList; 1400 tcu::Vec4 pixelConverted; 1401 tcu::Vec4 pixelReference; 1402 tcu::Vec4 pixelExpected; 1403 1404 this->readResultTextures(); 1405 this->storeResultPixels(pixelResultList); 1406 1407 pixelConverted = tcu::sRGBToLinear(pixelResultList[resultColorIdx]); 1408 pixelReference = this->formatReferenceColor(getColorReferenceLinear()); 1409 pixelExpected = this->formatReferenceColor(getColorReferenceSRGB()); 1410 1411 this->formatReferenceColor(pixelReference); 1412 this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected); 1413 1414 // result color 0 should be sRGB. Compare with linear reference color 1415 if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) ) 1416 { 1417 log << tcu::TestLog::Message << std::string("sRGB as expected") << tcu::TestLog::EndMessage; 1418 return true; 1419 } 1420 else 1421 { 1422 log << tcu::TestLog::Message << std::string("not sRGB as expected") << tcu::TestLog::EndMessage; 1423 return false; 1424 } 1425 } 1426 1427 class TextureDecodeEnabledCase : public SRGBTestCase 1428 { 1429 public: 1430 TextureDecodeEnabledCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1431 : SRGBTestCase (context, name, description, internalFormat) {} 1432 1433 ~TextureDecodeEnabledCase (void) {} 1434 1435 void setupTest (void); 1436 bool verifyResult (void); 1437 }; 1438 1439 void TextureDecodeEnabledCase::setupTest (void) 1440 { 1441 // TEST STEPS: 1442 // - create and set texture to DECODE_EXT 1443 // - store texture on GPU 1444 // - in fragment shader, sample the texture using texture*() and render texel values to a color attachment in the FBO 1445 // - on the host, read back the pixel values into a tcu::TextureLevel 1446 // - analyse the texel values, expecting them in lRGB format i.e. linear space decoding was enabled 1447 1448 FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1449 1450 this->addTexture( TEXTURETYPE_2D, 1451 TestDimensions::WIDTH, 1452 TestDimensions::HEIGHT, 1453 getColorReferenceLinear(), 1454 tcu::Sampler::MIRRORED_REPEAT_GL, 1455 tcu::Sampler::MIRRORED_REPEAT_GL, 1456 tcu::Sampler::LINEAR, 1457 tcu::Sampler::LINEAR, 1458 SRGBDECODE_DECODE); 1459 1460 this->addShaderProgram(shaderParameters); 1461 1462 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1463 1464 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE); 1465 } 1466 1467 bool TextureDecodeEnabledCase::verifyResult (void) 1468 { 1469 tcu::TestLog& log = m_context.getTestContext().getLog(); 1470 const int resultColorIdx = 0; 1471 std::vector<tcu::Vec4> pixelResultList; 1472 tcu::Vec4 pixelConverted; 1473 tcu::Vec4 pixelReference; 1474 tcu::Vec4 pixelExpected; 1475 1476 this->readResultTextures(); 1477 this->storeResultPixels(pixelResultList); 1478 1479 pixelConverted = tcu::linearToSRGB(pixelResultList[resultColorIdx]); 1480 pixelReference = this->formatReferenceColor(getColorReferenceSRGB()); 1481 pixelExpected = this->formatReferenceColor(getColorReferenceLinear()); 1482 1483 this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected); 1484 1485 // result color 0 should be SRGB. Compare with sRGB reference color 1486 if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) ) 1487 { 1488 log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage; 1489 return true; 1490 } 1491 else 1492 { 1493 log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage; 1494 return false; 1495 } 1496 } 1497 1498 class TexelFetchDecodeSkippedcase : public SRGBTestCase 1499 { 1500 public: 1501 TexelFetchDecodeSkippedcase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1502 : SRGBTestCase (context, name, description, internalFormat) {} 1503 1504 ~TexelFetchDecodeSkippedcase (void) {} 1505 1506 void setupTest (void); 1507 bool verifyResult (void); 1508 }; 1509 1510 void TexelFetchDecodeSkippedcase::setupTest (void) 1511 { 1512 // TEST STEPS: 1513 // - create and set texture to DECODE_SKIP_EXT 1514 // - store texture on GPU 1515 // - in fragment shader, sample the texture using texelFetch*() and render texel values to a color attachment in the FBO 1516 // - on the host, read back the pixel values into a tcu::TextureLevel 1517 // - analyse the texel values, expecting them in lRGB format i.e. linear space decoding is always enabled with texelFetch*() 1518 1519 FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1520 1521 this->addTexture( TEXTURETYPE_2D, 1522 TestDimensions::WIDTH, 1523 TestDimensions::HEIGHT, 1524 getColorReferenceLinear(), 1525 tcu::Sampler::MIRRORED_REPEAT_GL, 1526 tcu::Sampler::MIRRORED_REPEAT_GL, 1527 tcu::Sampler::LINEAR, 1528 tcu::Sampler::LINEAR, 1529 SRGBDECODE_SKIP_DECODE); 1530 1531 this->addShaderProgram(shaderParameters); 1532 1533 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1534 1535 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXEL_FETCH); 1536 } 1537 1538 bool TexelFetchDecodeSkippedcase::verifyResult (void) 1539 { 1540 tcu::TestLog& log = m_context.getTestContext().getLog(); 1541 const int resultColorIdx = 0; 1542 std::vector<tcu::Vec4> pixelResultList; 1543 tcu::Vec4 pixelReference; 1544 tcu::Vec4 pixelExpected; 1545 1546 this->readResultTextures(); 1547 this->storeResultPixels(pixelResultList); 1548 1549 pixelReference = pixelExpected = this->formatReferenceColor(getColorReferenceLinear()); 1550 1551 this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected); 1552 1553 // result color 0 should be linear due to automatic conversion via texelFetch*(). Compare with linear reference color 1554 if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelResultList[0] - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelResultList[0], pixelReference))) ) 1555 { 1556 log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage; 1557 return true; 1558 } 1559 else 1560 { 1561 log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage; 1562 return false; 1563 } 1564 } 1565 1566 class GPUConversionDecodeEnabledCase : public SRGBTestCase 1567 { 1568 public: 1569 GPUConversionDecodeEnabledCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1570 : SRGBTestCase (context, name, description, internalFormat) {} 1571 1572 ~GPUConversionDecodeEnabledCase (void) {} 1573 1574 void setupTest (void); 1575 bool verifyResult (void); 1576 }; 1577 1578 void GPUConversionDecodeEnabledCase::setupTest (void) 1579 { 1580 // TEST STEPS: 1581 // - create and set texture_a to DECODE_SKIP_EXT and texture_b to default 1582 // - store textures on GPU 1583 // - in fragment shader, sample both textures using texture*() and manually perform sRGB to lRGB conversion on texture_b 1584 // - in fragment shader, compare converted texture_b with texture_a 1585 // - render green image for pass or red for fail 1586 1587 ComparisonFunction comparisonFunction("srgbToLinearCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionSRGBToLinearCheck()); 1588 1589 FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &comparisonFunction, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1590 1591 this->addTexture( TEXTURETYPE_2D, 1592 TestDimensions::WIDTH, 1593 TestDimensions::HEIGHT, 1594 getColorReferenceLinear(), 1595 tcu::Sampler::MIRRORED_REPEAT_GL, 1596 tcu::Sampler::MIRRORED_REPEAT_GL, 1597 tcu::Sampler::LINEAR, 1598 tcu::Sampler::LINEAR, 1599 SRGBDECODE_SKIP_DECODE); 1600 1601 this->addTexture( TEXTURETYPE_2D, 1602 TestDimensions::WIDTH, 1603 TestDimensions::HEIGHT, 1604 getColorReferenceLinear(), 1605 tcu::Sampler::MIRRORED_REPEAT_GL, 1606 tcu::Sampler::MIRRORED_REPEAT_GL, 1607 tcu::Sampler::LINEAR, 1608 tcu::Sampler::LINEAR, 1609 SRGBDECODE_DECODE_DEFAULT); 1610 1611 this->addShaderProgram(shaderParameters); 1612 1613 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1614 1615 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE); 1616 } 1617 1618 bool GPUConversionDecodeEnabledCase::verifyResult (void) 1619 { 1620 tcu::TestLog& log = m_context.getTestContext().getLog(); 1621 const int resultColorIdx = 0; 1622 std::vector<tcu::Vec4> pixelResultList; 1623 1624 this->readResultTextures(); 1625 this->storeResultPixels(pixelResultList); 1626 this->logColor(std::string("Expected color: "), resultColorIdx, getColorGreenPass()); 1627 1628 // result color returned from GPU is either green (pass) or fail (red) 1629 if ( tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], getColorGreenPass())) ) 1630 { 1631 log << tcu::TestLog::Message << std::string("returned pass color from GPU") << tcu::TestLog::EndMessage; 1632 return true; 1633 } 1634 else 1635 { 1636 log << tcu::TestLog::Message << std::string("returned fail color from GPU") << tcu::TestLog::EndMessage; 1637 return false; 1638 } 1639 } 1640 1641 class DecodeToggledCase : public SRGBTestCase 1642 { 1643 public: 1644 DecodeToggledCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1645 : SRGBTestCase (context, name, description, internalFormat) {} 1646 1647 ~DecodeToggledCase (void) {} 1648 1649 void render (void); 1650 void setupTest (void); 1651 bool verifyResult (void); 1652 }; 1653 1654 void DecodeToggledCase::render (void) 1655 { 1656 // override the base SRGBTestCase render function with the purpose of switching between shader programs, 1657 // toggling texture sRGB decode state between draw calls 1658 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1659 1660 gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer); 1661 gl.bindVertexArray(m_vaoID); 1662 1663 for (std::size_t programIdx = 0; programIdx < m_shaderProgramList.size(); programIdx++) 1664 { 1665 gl.useProgram(m_shaderProgramList[programIdx]->getHandle()); 1666 1667 this->toggleDecode(m_shaderProgramList[programIdx]->getUniformDataList()); 1668 1669 for (int textureSourceIdx = 0; textureSourceIdx < (int)m_textureSourceList.size(); textureSourceIdx++) 1670 { 1671 gl.activeTexture(GL_TEXTURE0 + (glw::GLenum)textureSourceIdx); 1672 gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), m_textureSourceList[textureSourceIdx]->getHandle()); 1673 glw::GLuint samplerUniformLocationID = gl.getUniformLocation(m_shaderProgramList[programIdx]->getHandle(), (std::string("uTexture") + de::toString(textureSourceIdx)).c_str()); 1674 TCU_CHECK(samplerUniformLocationID != (glw::GLuint) - 1); 1675 gl.uniform1i(samplerUniformLocationID, (glw::GLenum)textureSourceIdx); 1676 } 1677 1678 for (int samplerIdx = 0; samplerIdx < (int)m_samplerList.size(); samplerIdx++) 1679 { 1680 if (m_samplerList[samplerIdx]->getIsActive() == true) 1681 { 1682 m_samplerList[samplerIdx]->bindToTexture(); 1683 } 1684 } 1685 1686 if (m_shaderProgramList[programIdx]->getBlendRequired() == true) 1687 { 1688 gl.enable(GL_BLEND); 1689 gl.blendEquation(GL_MAX); 1690 gl.blendFunc(GL_ONE, GL_ONE); 1691 } 1692 else 1693 { 1694 gl.disable(GL_BLEND); 1695 } 1696 1697 gl.drawArrays(GL_TRIANGLES, 0, 6); 1698 1699 // reset sRGB decode state on textures 1700 this->toggleDecode(m_shaderProgramList[programIdx]->getUniformDataList()); 1701 } 1702 1703 for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++) 1704 { 1705 gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), 0); 1706 } 1707 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1708 gl.bindVertexArray(0); 1709 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 1710 } 1711 1712 void DecodeToggledCase::setupTest (void) 1713 { 1714 // TEST STEPS: 1715 // - create and set texture_a to DECODE_SKIP_EXT and texture_b to DECODE_EXT 1716 // - create and use two seperate shader programs, program_a and program_b, each using different fragment shaders 1717 // - store texture_a and texture_b on GPU 1718 // FIRST PASS: 1719 // - use program_a 1720 // - in fragment shader, sample both textures using texture*() and manually perform sRGB to lRGB conversion on texture_a 1721 // - in fragment shader, test converted texture_a value with texture_b 1722 // - render green image for pass or red for fail 1723 // - store result in a color attachement 0 1724 // TOGGLE STAGE 1725 // - during rendering, toggle texture_a from DECODE_SKIP_EXT to DECODE_EXT 1726 // SECOND PASS: 1727 // - use program_b 1728 // - in fragment shader, sample both textures using texture*() and manually perform equality check. Both should be linear 1729 // - blend first pass result with second pass. Anything but a green result equals fail 1730 1731 ComparisonFunction srgbToLinearFunction("srgbToLinearCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionSRGBToLinearCheck()); 1732 ComparisonFunction colorsEqualFunction("colorsEqualCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionEqualCheck()); 1733 1734 FragmentShaderParameters shaderParametersA(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &srgbToLinearFunction, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1735 FragmentShaderParameters shaderParametersB(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &colorsEqualFunction, BLENDING_REQUIRED, TOGGLING_REQUIRED); 1736 1737 // need to specify which texture uniform to toggle DECODE_EXT/SKIP_DECODE_EXT 1738 shaderParametersB.uniformsToToggle.push_back("uTexture0"); 1739 1740 this->addTexture( TEXTURETYPE_2D, 1741 TestDimensions::WIDTH, 1742 TestDimensions::HEIGHT, 1743 getColorReferenceLinear(), 1744 tcu::Sampler::MIRRORED_REPEAT_GL, 1745 tcu::Sampler::MIRRORED_REPEAT_GL, 1746 tcu::Sampler::LINEAR, 1747 tcu::Sampler::LINEAR, 1748 SRGBDECODE_SKIP_DECODE); 1749 1750 this->addTexture( TEXTURETYPE_2D, 1751 TestDimensions::WIDTH, 1752 TestDimensions::HEIGHT, 1753 getColorReferenceLinear(), 1754 tcu::Sampler::MIRRORED_REPEAT_GL, 1755 tcu::Sampler::MIRRORED_REPEAT_GL, 1756 tcu::Sampler::LINEAR, 1757 tcu::Sampler::LINEAR, 1758 SRGBDECODE_DECODE); 1759 1760 this->addShaderProgram(shaderParametersA); 1761 this->addShaderProgram(shaderParametersB); 1762 1763 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1764 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE); 1765 } 1766 1767 bool DecodeToggledCase::verifyResult (void) 1768 { 1769 tcu::TestLog& log = m_context.getTestContext().getLog(); 1770 const int resultColorIdx = 0; 1771 std::vector<tcu::Vec4> pixelResultList; 1772 1773 this->readResultTextures(); 1774 this->storeResultPixels(pixelResultList); 1775 this->logColor(std::string("Expected color: "), resultColorIdx, getColorGreenPass()); 1776 1777 // result color is either green (pass) or fail (red) 1778 if ( tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], getColorGreenPass())) ) 1779 { 1780 log << tcu::TestLog::Message << std::string("returned pass color from GPU") << tcu::TestLog::EndMessage; 1781 return true; 1782 } 1783 else 1784 { 1785 log << tcu::TestLog::Message << std::string("returned fail color from GPU") << tcu::TestLog::EndMessage; 1786 return false; 1787 } 1788 } 1789 1790 class DecodeMultipleTexturesCase : public SRGBTestCase 1791 { 1792 public: 1793 DecodeMultipleTexturesCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1794 : SRGBTestCase (context, name, description, internalFormat) {} 1795 1796 ~DecodeMultipleTexturesCase (void) {} 1797 1798 void setupTest (void); 1799 bool verifyResult (void); 1800 }; 1801 1802 void DecodeMultipleTexturesCase::setupTest (void) 1803 { 1804 // TEST STEPS: 1805 // - create and set texture_a to DECODE_SKIP_EXT and texture_b to DECODE_EXT 1806 // - upload textures to the GPU and bind to seperate uniform variables 1807 // - sample both textures using texture*() 1808 // - read texel values back to the CPU 1809 // - compare the texel values, both should be different from each other 1810 1811 FragmentShaderParameters shaderParameters(SHADEROUTPUTS_TWO, SHADERUNIFORMS_TWO, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1812 1813 this->addTexture( TEXTURETYPE_2D, 1814 TestDimensions::WIDTH, 1815 TestDimensions::HEIGHT, 1816 getColorReferenceLinear(), 1817 tcu::Sampler::MIRRORED_REPEAT_GL, 1818 tcu::Sampler::MIRRORED_REPEAT_GL, 1819 tcu::Sampler::LINEAR, 1820 tcu::Sampler::LINEAR, 1821 SRGBDECODE_SKIP_DECODE); 1822 1823 this->addTexture( TEXTURETYPE_2D, 1824 TestDimensions::WIDTH, 1825 TestDimensions::HEIGHT, 1826 getColorReferenceLinear(), 1827 tcu::Sampler::MIRRORED_REPEAT_GL, 1828 tcu::Sampler::MIRRORED_REPEAT_GL, 1829 tcu::Sampler::LINEAR, 1830 tcu::Sampler::LINEAR, 1831 SRGBDECODE_DECODE); 1832 1833 this->addShaderProgram(shaderParameters); 1834 1835 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1836 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE); 1837 } 1838 1839 bool DecodeMultipleTexturesCase::verifyResult (void) 1840 { 1841 tcu::TestLog& log = m_context.getTestContext().getLog(); 1842 const int resultColorIdx = 0; 1843 std::vector<tcu::Vec4> pixelResultList; 1844 tcu::Vec4 pixelExpected0; 1845 tcu::Vec4 pixelExpected1; 1846 1847 this->readResultTextures(); 1848 this->storeResultPixels(pixelResultList); 1849 1850 pixelExpected0 = this->formatReferenceColor(getColorReferenceSRGB()); 1851 pixelExpected1 = this->formatReferenceColor(getColorReferenceLinear()); 1852 1853 this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected0); 1854 this->logColor(std::string("Expected color: "), resultColorIdx +1, pixelExpected1); 1855 1856 // check if the two textures have different values i.e. uTexture0 = sRGB and uTexture1 = linear 1857 if ( !(tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], pixelResultList[resultColorIdx +1]))) ) 1858 { 1859 log << tcu::TestLog::Message << std::string("texel values are different") << tcu::TestLog::EndMessage; 1860 return true; 1861 } 1862 else 1863 { 1864 log << tcu::TestLog::Message << std::string("texel values are equal") << tcu::TestLog::EndMessage; 1865 return false; 1866 } 1867 } 1868 1869 class DecodeSamplerCase : public SRGBTestCase 1870 { 1871 public: 1872 DecodeSamplerCase (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat) 1873 : SRGBTestCase (context, name, description, internalFormat) {} 1874 1875 ~DecodeSamplerCase (void) {} 1876 1877 void setupTest (void); 1878 bool verifyResult (void); 1879 }; 1880 1881 void DecodeSamplerCase::setupTest (void) 1882 { 1883 // TEST STEPS: 1884 // - create and set texture_a to DECODE_SKIP_EXT 1885 // - upload texture to the GPU and bind to sampler 1886 // - sample texture using texture*() 1887 // - read texel values back to the CPU 1888 // - compare the texel values, should be in sampler format (linear) 1889 1890 FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED); 1891 1892 this->addTexture( TEXTURETYPE_2D, 1893 TestDimensions::WIDTH, 1894 TestDimensions::HEIGHT, 1895 getColorReferenceLinear(), 1896 tcu::Sampler::MIRRORED_REPEAT_GL, 1897 tcu::Sampler::MIRRORED_REPEAT_GL, 1898 tcu::Sampler::LINEAR, 1899 tcu::Sampler::LINEAR, 1900 SRGBDECODE_SKIP_DECODE); 1901 1902 this->addSampler( tcu::Sampler::MIRRORED_REPEAT_GL, 1903 tcu::Sampler::MIRRORED_REPEAT_GL, 1904 tcu::Sampler::LINEAR, 1905 tcu::Sampler::LINEAR, 1906 SRGBDECODE_DECODE); 1907 1908 this->addShaderProgram(shaderParameters); 1909 1910 this->bindSamplerToTexture(0, 0, GL_TEXTURE0); 1911 this->activateSampler(0, true); 1912 1913 this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS); 1914 this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE); 1915 } 1916 1917 bool DecodeSamplerCase::verifyResult (void) 1918 { 1919 tcu::TestLog& log = m_context.getTestContext().getLog(); 1920 const int resultColorIdx = 0; 1921 std::vector<tcu::Vec4> pixelResultList; 1922 tcu::Vec4 pixelConverted; 1923 tcu::Vec4 pixelReference; 1924 tcu::Vec4 pixelExpected; 1925 1926 this->readResultTextures(); 1927 this->storeResultPixels(pixelResultList); 1928 1929 pixelConverted = tcu::linearToSRGB(pixelResultList[resultColorIdx]); 1930 pixelReference = this->formatReferenceColor(getColorReferenceSRGB()); 1931 pixelExpected = this->formatReferenceColor(getColorReferenceLinear()); 1932 1933 this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected); 1934 1935 // texture was rendered using a sampler object with setting DECODE_EXT, therefore, results should be linear 1936 if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) ) 1937 { 1938 log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage; 1939 return true; 1940 } 1941 else 1942 { 1943 log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage; 1944 return false; 1945 } 1946 } 1947 1948 } // anonymous 1949 1950 SRGBDecodeTests::SRGBDecodeTests (Context& context) 1951 : TestCaseGroup (context, "skip_decode", "sRGB skip decode tests") 1952 { 1953 } 1954 1955 SRGBDecodeTests::~SRGBDecodeTests (void) 1956 { 1957 } 1958 1959 void SRGBDecodeTests::init (void) 1960 { 1961 const TestGroupConfig testGroupConfigList[] = 1962 { 1963 TestGroupConfig("srgba8", "srgb decode tests using srgba internal format", tcu::TextureFormat(tcu::TextureFormat::sRGBA, tcu::TextureFormat::UNORM_INT8)), 1964 TestGroupConfig("sr8", "srgb decode tests using sr8 internal format", tcu::TextureFormat(tcu::TextureFormat::sR, tcu::TextureFormat::UNORM_INT8)) 1965 }; 1966 1967 // create groups for all desired internal formats, adding test cases to each 1968 for (std::size_t idx = 0; idx < DE_LENGTH_OF_ARRAY(testGroupConfigList); idx++) 1969 { 1970 tcu::TestCaseGroup* const testGroup = new tcu::TestCaseGroup(m_testCtx, testGroupConfigList[idx].name, testGroupConfigList[idx].description); 1971 tcu::TestNode::addChild(testGroup); 1972 1973 testGroup->addChild(new TextureDecodeSkippedCase (m_context, "skipped", "testing for sRGB color values with sRGB texture decoding skipped", testGroupConfigList[idx].internalFormat)); 1974 testGroup->addChild(new TextureDecodeEnabledCase (m_context, "enabled", "testing for linear color values with sRGB texture decoding enabled", testGroupConfigList[idx].internalFormat)); 1975 testGroup->addChild(new TexelFetchDecodeSkippedcase (m_context, "texel_fetch", "testing for linear color values with sRGB texture decoding skipped", testGroupConfigList[idx].internalFormat)); 1976 testGroup->addChild(new GPUConversionDecodeEnabledCase (m_context, "conversion_gpu", "sampling linear values and performing conversion on the gpu", testGroupConfigList[idx].internalFormat)); 1977 testGroup->addChild(new DecodeToggledCase (m_context, "toggled", "toggle the sRGB decoding between draw calls", testGroupConfigList[idx].internalFormat)); 1978 testGroup->addChild(new DecodeMultipleTexturesCase (m_context, "multiple_textures","upload multiple textures with different sRGB decode values and sample",testGroupConfigList[idx].internalFormat)); 1979 testGroup->addChild(new DecodeSamplerCase (m_context, "using_sampler", "testing that sampler object takes priority over texture state", testGroupConfigList[idx].internalFormat)); 1980 } 1981 } 1982 1983 } // Functional 1984 } // gles31 1985 } // deqp 1986