1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2015 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 border clamp tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fTextureBorderClampTests.hpp" 25 26 #include "glsTextureTestUtil.hpp" 27 28 #include "tcuTextureUtil.hpp" 29 #include "tcuTexLookupVerifier.hpp" 30 #include "tcuTexCompareVerifier.hpp" 31 #include "tcuCompressedTexture.hpp" 32 #include "tcuResultCollector.hpp" 33 #include "tcuSurface.hpp" 34 #include "tcuSeedBuilder.hpp" 35 #include "tcuVectorUtil.hpp" 36 37 #include "rrGenericVector.hpp" 38 39 #include "gluContextInfo.hpp" 40 #include "gluTexture.hpp" 41 #include "gluTextureUtil.hpp" 42 #include "gluPixelTransfer.hpp" 43 #include "gluStrUtil.hpp" 44 #include "gluObjectWrapper.hpp" 45 #include "gluShaderProgram.hpp" 46 #include "gluDrawUtil.hpp" 47 48 #include "glwEnums.hpp" 49 #include "glwFunctions.hpp" 50 51 #include "deStringUtil.hpp" 52 #include "deUniquePtr.hpp" 53 #include "deRandom.hpp" 54 55 #include <limits> 56 57 58 namespace deqp 59 { 60 namespace gles31 61 { 62 namespace Functional 63 { 64 namespace 65 { 66 67 enum SizeType 68 { 69 SIZE_POT = 0, 70 SIZE_NPOT 71 }; 72 73 bool filterRequiresFilterability (deUint32 filter) 74 { 75 switch (filter) 76 { 77 case GL_NEAREST: 78 case GL_NEAREST_MIPMAP_NEAREST: 79 return false; 80 81 case GL_LINEAR: 82 case GL_LINEAR_MIPMAP_NEAREST: 83 case GL_NEAREST_MIPMAP_LINEAR: 84 case GL_LINEAR_MIPMAP_LINEAR: 85 return true; 86 87 default: 88 DE_ASSERT(false); 89 return false; 90 } 91 } 92 93 bool isDepthFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode) 94 { 95 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA) 96 { 97 // Unsized formats are a special case 98 return false; 99 } 100 else if (glu::isCompressedFormat(format)) 101 { 102 // no known compressed depth formats 103 return false; 104 } 105 else 106 { 107 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format); 108 109 if (fmt.order == tcu::TextureFormat::D) 110 { 111 DE_ASSERT(mode == tcu::Sampler::MODE_DEPTH); 112 return true; 113 } 114 else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_DEPTH) 115 return true; 116 else 117 return false; 118 } 119 } 120 121 bool isStencilFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode) 122 { 123 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA) 124 { 125 // Unsized formats are a special case 126 return false; 127 } 128 else if (glu::isCompressedFormat(format)) 129 { 130 // no known compressed stencil formats 131 return false; 132 } 133 else 134 { 135 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format); 136 137 if (fmt.order == tcu::TextureFormat::S) 138 { 139 DE_ASSERT(mode == tcu::Sampler::MODE_STENCIL); 140 return true; 141 } 142 else if (fmt.order == tcu::TextureFormat::DS && mode == tcu::Sampler::MODE_STENCIL) 143 return true; 144 else 145 return false; 146 } 147 } 148 149 tcu::TextureChannelClass getFormatChannelClass (deUint32 format, tcu::Sampler::DepthStencilMode mode) 150 { 151 if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA || format == GL_ALPHA || format == GL_BGRA) 152 { 153 // Unsized formats are a special c, use UNORM8 154 return tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; 155 } 156 else if (glu::isCompressedFormat(format)) 157 { 158 const tcu::CompressedTexFormat compressedFmt = glu::mapGLCompressedTexFormat(format); 159 const tcu::TextureFormat uncompressedFmt = tcu::getUncompressedFormat(compressedFmt); 160 return tcu::getTextureChannelClass(uncompressedFmt.type); 161 } 162 else 163 { 164 const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format); 165 const tcu::TextureFormat effectiveFmt = tcu::getEffectiveDepthStencilTextureFormat(fmt, mode); 166 167 return tcu::getTextureChannelClass(effectiveFmt.type); 168 } 169 } 170 171 int getDimensionNumBlocks (int dimensionSize, int blockSize) 172 { 173 // ceil( a / b ) 174 return (dimensionSize + blockSize - 1) / blockSize; 175 } 176 177 void generateDummyCompressedData (tcu::CompressedTexture& dst, const tcu::CompressedTexFormat& format) 178 { 179 const int blockByteSize = tcu::getBlockSize(format); 180 const tcu::IVec3 blockPixelSize = tcu::getBlockPixelSize(format); 181 const tcu::IVec3 numBlocks (getDimensionNumBlocks(dst.getWidth(), blockPixelSize.x()), 182 getDimensionNumBlocks(dst.getHeight(), blockPixelSize.y()), 183 getDimensionNumBlocks(dst.getDepth(), blockPixelSize.z())); 184 const int numTotalBlocks = numBlocks.x() * numBlocks.y() * numBlocks.z(); 185 const int dataSize = numTotalBlocks * blockByteSize; 186 187 DE_ASSERT(dst.getDataSize() == dataSize); 188 189 if (tcu::isAstcFormat(format)) 190 { 191 // generate data that is valid in LDR mode 192 const int BLOCK_SIZE = 16; 193 const deUint8 block[BLOCK_SIZE] = { 252, 253, 255, 255, 255, 255, 255, 255, 223, 251, 28, 206, 54, 251, 160, 174 }; 194 195 DE_ASSERT(blockByteSize == BLOCK_SIZE); 196 for (int ndx = 0; ndx < numTotalBlocks; ++ndx) 197 deMemcpy((deUint8*)dst.getData() + ndx * BLOCK_SIZE, block, BLOCK_SIZE); 198 } 199 else 200 { 201 // any data is ok 202 de::Random rnd(0xabc); 203 204 for (int ndx = 0; ndx < dataSize; ++ndx) 205 ((deUint8*)dst.getData())[ndx] = rnd.getUint8(); 206 } 207 } 208 209 template <typename T> 210 struct TextureTraits 211 { 212 }; 213 214 template <> 215 struct TextureTraits<glu::Texture2D> 216 { 217 typedef tcu::IVec2 SizeType; 218 219 static de::MovePtr<glu::Texture2D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec2& size) 220 { 221 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, size.x(), size.y())); 222 } 223 224 static de::MovePtr<glu::Texture2D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec2& size) 225 { 226 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, texFormat, type, size.x(), size.y())); 227 } 228 229 static de::MovePtr<glu::Texture2D> createTextureFromCompressedData (glu::RenderContext& renderCtx, 230 const glu::ContextInfo& ctxInfo, 231 const tcu::CompressedTexture& compressedLevel, 232 const tcu::TexDecompressionParams& decompressionParams) 233 { 234 return de::MovePtr<glu::Texture2D>(new glu::Texture2D(renderCtx, 235 ctxInfo, 236 1, 237 &compressedLevel, 238 decompressionParams)); 239 } 240 241 static int getTextureNumLayers (const tcu::IVec2& size) 242 { 243 // 2D textures have one layer 244 DE_UNREF(size); 245 return 1; 246 } 247 }; 248 249 template <> 250 struct TextureTraits<glu::Texture3D> 251 { 252 typedef tcu::IVec3 SizeType; 253 254 static de::MovePtr<glu::Texture3D> createTextureFromInternalFormat (glu::RenderContext& renderCtx, deUint32 texFormat, const tcu::IVec3& size) 255 { 256 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, size.x(), size.y(), size.z())); 257 } 258 259 static de::MovePtr<glu::Texture3D> createTextureFromFormatAndType (glu::RenderContext& renderCtx, deUint32 texFormat, deUint32 type, const tcu::IVec3& size) 260 { 261 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, texFormat, type, size.x(), size.y(), size.z())); 262 } 263 264 static de::MovePtr<glu::Texture3D> createTextureFromCompressedData (glu::RenderContext& renderCtx, 265 const glu::ContextInfo& ctxInfo, 266 const tcu::CompressedTexture& compressedLevel, 267 const tcu::TexDecompressionParams& decompressionParams) 268 { 269 return de::MovePtr<glu::Texture3D>(new glu::Texture3D(renderCtx, 270 ctxInfo, 271 1, 272 &compressedLevel, 273 decompressionParams)); 274 } 275 276 static int getTextureNumLayers (const tcu::IVec3& size) 277 { 278 // 3D textures have Z layers 279 return size.z(); 280 } 281 }; 282 283 template <typename T> 284 de::MovePtr<T> genDummyTexture (glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, deUint32 texFormat, const typename TextureTraits<T>::SizeType& size) 285 { 286 de::MovePtr<T> texture; 287 288 if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH) || isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL)) 289 { 290 // fill different channels with different gradients 291 texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size); 292 texture->getRefTexture().allocLevel(0); 293 294 if (isDepthFormat(texFormat, tcu::Sampler::MODE_DEPTH)) 295 { 296 // fill depth with 0 -> 1 297 const tcu::PixelBufferAccess depthAccess = tcu::getEffectiveDepthStencilAccess(texture->getRefTexture().getLevel(0), tcu::Sampler::MODE_DEPTH); 298 tcu::fillWithComponentGradients(depthAccess, tcu::Vec4(0.0f), tcu::Vec4(1.0f)); 299 } 300 301 if (isStencilFormat(texFormat, tcu::Sampler::MODE_STENCIL)) 302 { 303 // fill stencil with 0 -> max 304 const tcu::PixelBufferAccess stencilAccess = tcu::getEffectiveDepthStencilAccess(texture->getRefTexture().getLevel(0), tcu::Sampler::MODE_STENCIL); 305 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(stencilAccess.getFormat()); 306 307 // Flip y to make stencil and depth cases not look identical 308 tcu::fillWithComponentGradients(tcu::flipYAccess(stencilAccess), texFormatInfo.valueMax, texFormatInfo.valueMin); 309 } 310 311 texture->upload(); 312 } 313 else if (!glu::isCompressedFormat(texFormat)) 314 { 315 if (texFormat == GL_LUMINANCE || texFormat == GL_LUMINANCE_ALPHA || texFormat == GL_ALPHA || texFormat == GL_BGRA) 316 texture = TextureTraits<T>::createTextureFromFormatAndType(renderCtx, texFormat, GL_UNSIGNED_BYTE, size); 317 else 318 texture = TextureTraits<T>::createTextureFromInternalFormat(renderCtx, texFormat, size); 319 320 // Fill level 0. 321 texture->getRefTexture().allocLevel(0); 322 323 // fill with gradient min -> max 324 { 325 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texture->getRefTexture().getFormat()); 326 const tcu::Vec4 rampLow = texFormatInfo.valueMin; 327 const tcu::Vec4 rampHigh = texFormatInfo.valueMax; 328 tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(0), rampLow, rampHigh); 329 } 330 331 texture->upload(); 332 } 333 else 334 { 335 const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(texFormat); 336 const int numLayers = TextureTraits<T>::getTextureNumLayers(size); 337 tcu::CompressedTexture compressedLevel (compressedFormat, size.x(), size.y(), numLayers); 338 const bool isAstcFormat = tcu::isAstcFormat(compressedFormat); 339 tcu::TexDecompressionParams decompressionParams ((isAstcFormat) ? (tcu::TexDecompressionParams::ASTCMODE_LDR) : (tcu::TexDecompressionParams::ASTCMODE_LAST)); 340 341 generateDummyCompressedData(compressedLevel, compressedFormat); 342 343 texture = TextureTraits<T>::createTextureFromCompressedData(renderCtx, 344 ctxInfo, 345 compressedLevel, 346 decompressionParams); 347 } 348 349 return texture; 350 } 351 352 int getNBitIntegerMaxValue (bool isSigned, int numBits) 353 { 354 DE_ASSERT(numBits < 32); 355 356 if (numBits == 0) 357 return 0; 358 else if (isSigned) 359 return deIntMaxValue32(numBits); 360 else 361 return deUintMaxValue32(numBits); 362 } 363 364 int getNBitIntegerMinValue (bool isSigned, int numBits) 365 { 366 DE_ASSERT(numBits < 32); 367 368 if (numBits == 0) 369 return 0; 370 else if (isSigned) 371 return deIntMinValue32(numBits); 372 else 373 return 0; 374 } 375 376 tcu::IVec4 getNBitIntegerVec4MaxValue (bool isSigned, const tcu::IVec4& numBits) 377 { 378 return tcu::IVec4(getNBitIntegerMaxValue(isSigned, numBits[0]), 379 getNBitIntegerMaxValue(isSigned, numBits[1]), 380 getNBitIntegerMaxValue(isSigned, numBits[2]), 381 getNBitIntegerMaxValue(isSigned, numBits[3])); 382 } 383 384 tcu::IVec4 getNBitIntegerVec4MinValue (bool isSigned, const tcu::IVec4& numBits) 385 { 386 return tcu::IVec4(getNBitIntegerMinValue(isSigned, numBits[0]), 387 getNBitIntegerMinValue(isSigned, numBits[1]), 388 getNBitIntegerMinValue(isSigned, numBits[2]), 389 getNBitIntegerMinValue(isSigned, numBits[3])); 390 } 391 392 rr::GenericVec4 mapToFormatColorUnits (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange) 393 { 394 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat); 395 396 switch (tcu::getTextureChannelClass(texFormat.type)) 397 { 398 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: return rr::GenericVec4(normalizedRange); 399 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: return rr::GenericVec4(normalizedRange * 2.0f - 1.0f); 400 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: return rr::GenericVec4(texFormatInfo.valueMin + normalizedRange * texFormatInfo.valueMax); 401 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: return rr::GenericVec4(tcu::mix(texFormatInfo.valueMin, texFormatInfo.valueMax, normalizedRange).cast<deInt32>()); 402 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: return rr::GenericVec4(tcu::mix(texFormatInfo.valueMin, texFormatInfo.valueMax, normalizedRange).cast<deUint32>()); 403 404 default: 405 DE_ASSERT(false); 406 return rr::GenericVec4(); 407 } 408 } 409 410 rr::GenericVec4 mapToFormatColorRepresentable (const tcu::TextureFormat& texFormat, const tcu::Vec4& normalizedRange) 411 { 412 // make sure value is representable in the target format and clear channels 413 // not present in the target format. 414 415 const rr::GenericVec4 inFormatUnits = mapToFormatColorUnits(texFormat, normalizedRange); 416 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(texFormat); 417 de::ArrayBuffer<deUint8, 4> buffer (texFormat.getPixelSize()); 418 tcu::PixelBufferAccess access (texFormat, tcu::IVec3(1, 1, 1), buffer.getPtr()); 419 420 if (tcu::isSRGB(texFormat)) 421 { 422 DE_ASSERT(texFormat.type == tcu::TextureFormat::UNORM_INT8); 423 424 // make sure border color (in linear space) can be converted to 8-bit sRGB space without 425 // significant loss. 426 const tcu::Vec4 sRGB = tcu::linearToSRGB(normalizedRange); 427 const tcu::IVec4 sRGB8 = tcu::IVec4(tcu::floatToU8(sRGB[0]), 428 tcu::floatToU8(sRGB[1]), 429 tcu::floatToU8(sRGB[2]), 430 tcu::floatToU8(sRGB[3])); 431 const tcu::Vec4 linearized = tcu::sRGBToLinear(tcu::Vec4(sRGB8[0] / 255.0f, 432 sRGB8[1] / 255.0f, 433 sRGB8[2] / 255.0f, 434 sRGB8[3] / 255.0f)); 435 436 return rr::GenericVec4(tcu::select(linearized, tcu::Vec4(0.0f), channelMask)); 437 } 438 439 switch (tcu::getTextureChannelClass(texFormat.type)) 440 { 441 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 442 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 443 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 444 { 445 access.setPixel(inFormatUnits.get<float>(), 0, 0); 446 return rr::GenericVec4(tcu::select(access.getPixel(0, 0), tcu::Vec4(0.0f), channelMask)); 447 } 448 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 449 { 450 access.setPixel(inFormatUnits.get<deInt32>(), 0, 0); 451 return rr::GenericVec4(tcu::select(access.getPixelInt(0, 0), tcu::IVec4(0), channelMask)); 452 } 453 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 454 { 455 access.setPixel(inFormatUnits.get<deUint32>(), 0, 0); 456 return rr::GenericVec4(tcu::select(access.getPixelUint(0, 0), tcu::UVec4(0u), channelMask)); 457 } 458 default: 459 { 460 DE_ASSERT(false); 461 return rr::GenericVec4(); 462 } 463 } 464 } 465 466 bool isCoreFilterableFormat (deUint32 format, tcu::Sampler::DepthStencilMode mode) 467 { 468 const bool isLuminanceOrAlpha = (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA); // special case for luminance/alpha 469 const bool isUnsizedColorFormat = (format == GL_BGRA); 470 const bool isCompressed = glu::isCompressedFormat(format); 471 const bool isDepth = isDepthFormat(format, mode); 472 const bool isStencil = isStencilFormat(format, mode); 473 474 // special cases 475 if (isLuminanceOrAlpha || isUnsizedColorFormat || isCompressed) 476 return true; 477 if (isStencil || isDepth) 478 return false; 479 480 // color case 481 return glu::isGLInternalColorFormatFilterable(format); 482 } 483 484 class TextureBorderClampTest : public TestCase 485 { 486 public: 487 enum StateType 488 { 489 STATE_SAMPLER_PARAM = 0, 490 STATE_TEXTURE_PARAM, 491 492 STATE_LAST 493 }; 494 495 enum SamplingFunction 496 { 497 SAMPLE_FILTER = 0, 498 SAMPLE_GATHER, 499 500 SAMPLE_LAST 501 }; 502 503 enum Flag 504 { 505 FLAG_USE_SHADOW_SAMPLER = (1u << 0), 506 }; 507 508 struct IterationConfig 509 { 510 tcu::Vec2 p0; 511 tcu::Vec2 p1; 512 rr::GenericVec4 borderColor; 513 tcu::Vec4 lookupScale; 514 tcu::Vec4 lookupBias; 515 deUint32 minFilter; 516 deUint32 magFilter; 517 std::string description; 518 deUint32 sWrapMode; 519 deUint32 tWrapMode; 520 deUint32 compareMode; 521 float compareRef; 522 }; 523 524 TextureBorderClampTest (Context& context, 525 const char* name, 526 const char* description, 527 deUint32 texFormat, 528 tcu::Sampler::DepthStencilMode mode, 529 StateType stateType, 530 int texWidth, 531 int texHeight, 532 SamplingFunction samplingFunction, 533 deUint32 flags = 0); 534 ~TextureBorderClampTest (void); 535 536 protected: 537 void init (void); 538 void deinit (void); 539 540 private: 541 IterateResult iterate (void); 542 543 void logParams (const IterationConfig& config, 544 const gls::TextureTestUtil::ReferenceParams& samplerParams); 545 546 void renderTo (tcu::Surface& surface, 547 const IterationConfig& config, 548 const gls::TextureTestUtil::ReferenceParams& samplerParams); 549 void renderQuad (const float* texCoord, 550 const gls::TextureTestUtil::ReferenceParams& samplerParams); 551 552 void verifyImage (const tcu::Surface& image, 553 const IterationConfig& config, 554 const gls::TextureTestUtil::ReferenceParams& samplerParams); 555 556 bool verifyTextureSampleResult (const tcu::ConstPixelBufferAccess& renderedFrame, 557 const float* texCoord, 558 const gls::TextureTestUtil::ReferenceParams& samplerParams, 559 const tcu::LodPrecision& lodPrecision, 560 const tcu::LookupPrecision& lookupPrecision); 561 562 bool verifyTextureCompareResult (const tcu::ConstPixelBufferAccess& renderedFrame, 563 const float* texCoord, 564 const gls::TextureTestUtil::ReferenceParams& samplerParams, 565 const tcu::TexComparePrecision& texComparePrecision, 566 const tcu::TexComparePrecision& lowQualityTexComparePrecision, 567 const tcu::LodPrecision& lodPrecision, 568 const tcu::LodPrecision& lowQualityLodPrecision); 569 570 bool verifyTextureGatherResult (const tcu::ConstPixelBufferAccess& renderedFrame, 571 const float* texCoord, 572 const gls::TextureTestUtil::ReferenceParams& samplerParams, 573 const tcu::LookupPrecision& lookupPrecision); 574 575 bool verifyTextureGatherCmpResult(const tcu::ConstPixelBufferAccess& renderedFrame, 576 const float* texCoord, 577 const gls::TextureTestUtil::ReferenceParams& samplerParams, 578 const tcu::TexComparePrecision& texComparePrecision, 579 const tcu::TexComparePrecision& lowQualityTexComparePrecision); 580 581 deUint32 getIterationSeed (const IterationConfig& config) const; 582 gls::TextureTestUtil::ReferenceParams genSamplerParams (const IterationConfig& config) const; 583 glu::ShaderProgram* genGatherProgram (void) const; 584 585 virtual int getNumIterations (void) const = 0; 586 virtual IterationConfig getIteration (int ndx) const = 0; 587 588 protected: 589 const glu::Texture2D* getTexture (void) const; 590 591 const deUint32 m_texFormat; 592 const tcu::Sampler::DepthStencilMode m_sampleMode; 593 const tcu::TextureChannelClass m_channelClass; 594 const StateType m_stateType; 595 596 const int m_texHeight; 597 const int m_texWidth; 598 599 const SamplingFunction m_samplingFunction; 600 const bool m_useShadowSampler; 601 private: 602 enum 603 { 604 VIEWPORT_WIDTH = 128, 605 VIEWPORT_HEIGHT = 128, 606 }; 607 608 de::MovePtr<glu::Texture2D> m_texture; 609 de::MovePtr<gls::TextureTestUtil::TextureRenderer> m_renderer; 610 de::MovePtr<glu::ShaderProgram> m_gatherProgram; 611 612 int m_iterationNdx; 613 tcu::ResultCollector m_result; 614 }; 615 616 TextureBorderClampTest::TextureBorderClampTest (Context& context, 617 const char* name, 618 const char* description, 619 deUint32 texFormat, 620 tcu::Sampler::DepthStencilMode mode, 621 StateType stateType, 622 int texWidth, 623 int texHeight, 624 SamplingFunction samplingFunction, 625 deUint32 flags) 626 : TestCase (context, name, description) 627 , m_texFormat (texFormat) 628 , m_sampleMode (mode) 629 , m_channelClass (getFormatChannelClass(texFormat, mode)) 630 , m_stateType (stateType) 631 , m_texHeight (texHeight) 632 , m_texWidth (texWidth) 633 , m_samplingFunction (samplingFunction) 634 , m_useShadowSampler ((flags & FLAG_USE_SHADOW_SAMPLER) != 0) 635 , m_iterationNdx (0) 636 , m_result (context.getTestContext().getLog()) 637 { 638 DE_ASSERT(stateType < STATE_LAST); 639 DE_ASSERT(samplingFunction < SAMPLE_LAST); 640 // mode must be set for combined depth-stencil formats 641 DE_ASSERT(m_channelClass != tcu::TEXTURECHANNELCLASS_LAST || mode != tcu::Sampler::MODE_LAST); 642 } 643 644 TextureBorderClampTest::~TextureBorderClampTest (void) 645 { 646 deinit(); 647 } 648 649 void TextureBorderClampTest::init (void) 650 { 651 // requirements 652 653 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp")) 654 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension"); 655 656 if (glu::isCompressedFormat(m_texFormat) && 657 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat)) && 658 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr")) 659 { 660 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension"); 661 } 662 663 if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888")) 664 throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension"); 665 666 if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH || 667 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT) 668 { 669 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport"); 670 } 671 672 // resources 673 674 m_texture = genDummyTexture<glu::Texture2D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, tcu::IVec2(m_texWidth, m_texHeight)); 675 676 m_testCtx.getLog() << tcu::TestLog::Message 677 << "Created texture with format " << ((glu::isCompressedFormat(m_texFormat)) ? (glu::getCompressedTexFormatName(m_texFormat)) : (glu::getPixelFormatName(m_texFormat))) 678 << ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ")\n" 679 << "Setting sampling state using " << ((m_stateType == STATE_TEXTURE_PARAM) ? ("texture state") : ("sampler state")) 680 << tcu::TestLog::EndMessage; 681 682 if (m_samplingFunction == SAMPLE_FILTER) 683 { 684 m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glu::GLSL_VERSION_310_ES, glu::PRECISION_HIGHP)); 685 } 686 else 687 { 688 m_gatherProgram = de::MovePtr<glu::ShaderProgram>(genGatherProgram()); 689 690 m_testCtx.getLog() << tcu::TestLog::Message 691 << "Using texture gather to sample texture" 692 << tcu::TestLog::EndMessage 693 << *m_gatherProgram; 694 695 if (!m_gatherProgram->isOk()) 696 throw tcu::TestError("failed to build program"); 697 } 698 } 699 700 void TextureBorderClampTest::deinit (void) 701 { 702 m_texture.clear(); 703 m_renderer.clear(); 704 m_gatherProgram.clear(); 705 } 706 707 TextureBorderClampTest::IterateResult TextureBorderClampTest::iterate (void) 708 { 709 const IterationConfig iterationConfig = getIteration(m_iterationNdx); 710 const std::string iterationDesc = "Iteration " + de::toString(m_iterationNdx+1) + (iterationConfig.description.empty() ? ("") : (" - " + iterationConfig.description)); 711 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Iteration", iterationDesc); 712 tcu::Surface renderedFrame (VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 713 const gls::TextureTestUtil::ReferenceParams samplerParams = genSamplerParams(iterationConfig); 714 715 logParams(iterationConfig, samplerParams); 716 renderTo(renderedFrame, iterationConfig, samplerParams); 717 verifyImage(renderedFrame, iterationConfig, samplerParams); 718 719 if (++m_iterationNdx == getNumIterations()) 720 { 721 m_result.setTestContextResult(m_testCtx); 722 return STOP; 723 } 724 return CONTINUE; 725 } 726 727 void TextureBorderClampTest::logParams (const IterationConfig& config, const gls::TextureTestUtil::ReferenceParams& samplerParams) 728 { 729 const std::string borderColorString = (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? (de::toString(config.borderColor.get<deInt32>())) 730 : (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(config.borderColor.get<deUint32>())) 731 : (de::toString(config.borderColor.get<float>())); 732 733 m_testCtx.getLog() << tcu::TestLog::Message 734 << "Rendering full screen quad, tex coords bottom-left: " << config.p0 << ", top-right " << config.p1 << "\n" 735 << "Border color is " << borderColorString << "\n" 736 << "Texture lookup bias: " << samplerParams.colorBias << "\n" 737 << "Texture lookup scale: " << samplerParams.colorScale << "\n" 738 << "Filters: min = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.minFilter)) 739 << ", mag = " << glu::getTextureFilterName(glu::getGLFilterMode(samplerParams.sampler.magFilter)) << "\n" 740 << "Wrap mode: s = " << glu::getRepeatModeStr(config.sWrapMode) 741 << ", t = " << glu::getRepeatModeStr(config.tWrapMode) << "\n" 742 << tcu::TestLog::EndMessage; 743 744 if (m_sampleMode == tcu::Sampler::MODE_DEPTH) 745 m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is DEPTH_COMPONENT" << tcu::TestLog::EndMessage; 746 else if (m_sampleMode == tcu::Sampler::MODE_STENCIL) 747 m_testCtx.getLog() << tcu::TestLog::Message << "Depth stencil texture mode is STENCIL_INDEX" << tcu::TestLog::EndMessage; 748 749 if (config.compareMode != GL_NONE) 750 { 751 m_testCtx.getLog() << tcu::TestLog::Message 752 << "Texture mode is COMPARE_REF_TO_TEXTURE, mode = " << glu::getCompareFuncStr(config.compareMode) << "\n" 753 << "Compare reference value = " << config.compareRef << "\n" 754 << tcu::TestLog::EndMessage; 755 } 756 } 757 758 void TextureBorderClampTest::renderTo (tcu::Surface& surface, 759 const IterationConfig& config, 760 const gls::TextureTestUtil::ReferenceParams& samplerParams) 761 { 762 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 763 const gls::TextureTestUtil::RandomViewport viewport (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getIterationSeed(config)); 764 std::vector<float> texCoord; 765 de::MovePtr<glu::Sampler> sampler; 766 767 gls::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1); 768 769 // Bind to unit 0. 770 gl.activeTexture(GL_TEXTURE0); 771 gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture()); 772 773 if (m_sampleMode == tcu::Sampler::MODE_DEPTH) 774 gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); 775 else if (m_sampleMode == tcu::Sampler::MODE_STENCIL) 776 gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); 777 778 if (config.compareMode == GL_NONE) 779 { 780 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); 781 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS); 782 } 783 else 784 { 785 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 786 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, config.compareMode); 787 } 788 789 if (m_stateType == STATE_TEXTURE_PARAM) 790 { 791 // Setup filtering and wrap modes. 792 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(samplerParams.sampler.wrapS)); 793 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(samplerParams.sampler.wrapT)); 794 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(samplerParams.sampler.minFilter)); 795 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(samplerParams.sampler.magFilter)); 796 797 switch (m_channelClass) 798 { 799 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 800 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 801 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 802 gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>()); 803 break; 804 805 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 806 gl.texParameterIiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>()); 807 break; 808 809 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 810 gl.texParameterIuiv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>()); 811 break; 812 813 default: 814 DE_ASSERT(false); 815 } 816 } 817 else if (m_stateType == STATE_SAMPLER_PARAM) 818 { 819 const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f); 820 821 // Setup filtering and wrap modes to bad values 822 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 823 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 824 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 825 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 826 gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, blue.getPtr()); // just set some unlikely color 827 828 // setup sampler to correct values 829 sampler = de::MovePtr<glu::Sampler>(new glu::Sampler(m_context.getRenderContext())); 830 831 gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(samplerParams.sampler.wrapS)); 832 gl.samplerParameteri(**sampler, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(samplerParams.sampler.wrapT)); 833 gl.samplerParameteri(**sampler, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(samplerParams.sampler.minFilter)); 834 gl.samplerParameteri(**sampler, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(samplerParams.sampler.magFilter)); 835 836 switch (m_channelClass) 837 { 838 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 839 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 840 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 841 gl.samplerParameterfv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<float>()); 842 break; 843 844 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 845 gl.samplerParameterIiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deInt32>()); 846 break; 847 848 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 849 gl.samplerParameterIuiv(**sampler, GL_TEXTURE_BORDER_COLOR, config.borderColor.getAccess<deUint32>()); 850 break; 851 852 default: 853 DE_ASSERT(false); 854 } 855 856 gl.bindSampler(0, **sampler); 857 } 858 859 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state"); 860 861 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); 862 renderQuad(&texCoord[0], samplerParams); 863 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess()); 864 } 865 866 void TextureBorderClampTest::renderQuad (const float* texCoord, const gls::TextureTestUtil::ReferenceParams& samplerParams) 867 { 868 // use TextureRenderer for basic rendering, use custom for gather 869 if (m_samplingFunction == SAMPLE_FILTER) 870 m_renderer->renderQuad(0, texCoord, samplerParams); 871 else 872 { 873 static const float position[] = 874 { 875 -1.0f, -1.0f, 0.0f, 1.0f, 876 -1.0f, +1.0f, 0.0f, 1.0f, 877 +1.0f, -1.0f, 0.0f, 1.0f, 878 +1.0f, +1.0f, 0.0f, 1.0f 879 }; 880 static const deUint16 indices[] = 881 { 882 0, 1, 2, 2, 1, 3 883 }; 884 const glu::VertexArrayBinding vertexArrays[] = 885 { 886 glu::va::Float("a_position", 4, 4, 0, &position[0]), 887 glu::va::Float("a_texcoord", 2, 4, 0, texCoord) 888 }; 889 890 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 891 const deUint32 progId = m_gatherProgram->getProgram(); 892 893 gl.useProgram(progId); 894 gl.uniform1i(gl.getUniformLocation(progId, "u_sampler"), 0); 895 if (m_useShadowSampler) 896 gl.uniform1f(gl.getUniformLocation(progId, "u_ref"), samplerParams.ref); 897 gl.uniform4fv(gl.getUniformLocation(progId, "u_colorScale"), 1, samplerParams.colorScale.getPtr()); 898 gl.uniform4fv(gl.getUniformLocation(progId, "u_colorBias"), 1, samplerParams.colorBias.getPtr()); 899 900 glu::draw(m_context.getRenderContext(), progId, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0], 901 glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 902 } 903 } 904 905 void TextureBorderClampTest::verifyImage (const tcu::Surface& renderedFrame, 906 const IterationConfig& config, 907 const gls::TextureTestUtil::ReferenceParams& samplerParams) 908 { 909 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat(); 910 911 tcu::LodPrecision lodPrecision; 912 std::vector<float> texCoord; 913 bool verificationOk; 914 915 gls::TextureTestUtil::computeQuadTexCoord2D(texCoord, config.p0, config.p1); 916 917 lodPrecision.derivateBits = 18; 918 lodPrecision.lodBits = 5; 919 920 if (samplerParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE) 921 { 922 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode); 923 const bool isNearestMinFilter = samplerParams.sampler.minFilter == tcu::Sampler::NEAREST || samplerParams.sampler.minFilter == tcu::Sampler::NEAREST_MIPMAP_NEAREST; 924 const bool isNearestMagFilter = samplerParams.sampler.magFilter == tcu::Sampler::NEAREST; 925 const bool isNearestOnly = isNearestMinFilter && isNearestMagFilter; 926 const bool isSRGB = texFormat.order == tcu::TextureFormat::sRGB || texFormat.order == tcu::TextureFormat::sRGBA; 927 const int colorErrorBits = (isNearestOnly && !isSRGB) ? (1) : (2); 928 const tcu::IVec4 colorBits = tcu::max(gls::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0)); 929 tcu::LookupPrecision lookupPrecision; 930 931 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale; 932 lookupPrecision.coordBits = tcu::IVec3(20,20,0); 933 lookupPrecision.uvwBits = tcu::IVec3(5,5,0); 934 lookupPrecision.colorMask = gls::TextureTestUtil::getCompareMask(pixelFormat); 935 936 if (m_samplingFunction == SAMPLE_FILTER) 937 { 938 verificationOk = verifyTextureSampleResult(renderedFrame.getAccess(), 939 &texCoord[0], 940 samplerParams, 941 lodPrecision, 942 lookupPrecision); 943 } 944 else if (m_samplingFunction == SAMPLE_GATHER) 945 { 946 verificationOk = verifyTextureGatherResult(renderedFrame.getAccess(), 947 &texCoord[0], 948 samplerParams, 949 lookupPrecision); 950 } 951 else 952 { 953 DE_ASSERT(false); 954 verificationOk = false; 955 } 956 } 957 else 958 { 959 tcu::TexComparePrecision texComparePrecision; 960 tcu::TexComparePrecision lowQualityTexComparePrecision; 961 tcu::LodPrecision lowQualityLodPrecision = lodPrecision; 962 963 texComparePrecision.coordBits = tcu::IVec3(20,20,0); 964 texComparePrecision.uvwBits = tcu::IVec3(7,7,0); 965 texComparePrecision.pcfBits = 5; 966 texComparePrecision.referenceBits = 16; 967 texComparePrecision.resultBits = de::max(0, pixelFormat.redBits - 1); 968 969 lowQualityTexComparePrecision.coordBits = tcu::IVec3(20,20,0); 970 lowQualityTexComparePrecision.uvwBits = tcu::IVec3(4,4,0); 971 lowQualityTexComparePrecision.pcfBits = 0; 972 lowQualityTexComparePrecision.referenceBits = 16; 973 lowQualityTexComparePrecision.resultBits = de::max(0, pixelFormat.redBits - 1); 974 975 lowQualityLodPrecision.lodBits = 4; 976 977 if (m_samplingFunction == SAMPLE_FILTER) 978 { 979 verificationOk = verifyTextureCompareResult(renderedFrame.getAccess(), 980 &texCoord[0], 981 samplerParams, 982 texComparePrecision, 983 lowQualityTexComparePrecision, 984 lodPrecision, 985 lowQualityLodPrecision); 986 } 987 else if (m_samplingFunction == SAMPLE_GATHER) 988 { 989 verificationOk = verifyTextureGatherCmpResult(renderedFrame.getAccess(), 990 &texCoord[0], 991 samplerParams, 992 texComparePrecision, 993 lowQualityTexComparePrecision); 994 } 995 else 996 { 997 DE_ASSERT(false); 998 verificationOk = false; 999 } 1000 } 1001 1002 if (!verificationOk) 1003 m_result.fail("Image verification failed"); 1004 } 1005 1006 bool TextureBorderClampTest::verifyTextureSampleResult (const tcu::ConstPixelBufferAccess& renderedFrame, 1007 const float* texCoord, 1008 const gls::TextureTestUtil::ReferenceParams& samplerParams, 1009 const tcu::LodPrecision& lodPrecision, 1010 const tcu::LookupPrecision& lookupPrecision) 1011 { 1012 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat(); 1013 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight()); 1014 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight()); 1015 int numFailedPixels; 1016 1017 gls::TextureTestUtil::sampleTexture(gls::TextureTestUtil::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), texCoord, samplerParams); 1018 1019 numFailedPixels = gls::TextureTestUtil::computeTextureLookupDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(), 1020 texCoord, samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog()); 1021 1022 if (numFailedPixels > 0) 1023 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1024 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1025 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame); 1026 if (numFailedPixels > 0) 1027 { 1028 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1029 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1030 } 1031 m_testCtx.getLog() << tcu::TestLog::EndImageSet; 1032 1033 return (numFailedPixels == 0); 1034 } 1035 1036 bool TextureBorderClampTest::verifyTextureCompareResult (const tcu::ConstPixelBufferAccess& renderedFrame, 1037 const float* texCoord, 1038 const gls::TextureTestUtil::ReferenceParams& samplerParams, 1039 const tcu::TexComparePrecision& texComparePrecision, 1040 const tcu::TexComparePrecision& lowQualityTexComparePrecision, 1041 const tcu::LodPrecision& lodPrecision, 1042 const tcu::LodPrecision& lowQualityLodPrecision) 1043 { 1044 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat(); 1045 const int colorErrorBits = 1; 1046 const tcu::IVec4 nonShadowBits = tcu::max(gls::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0)); 1047 const tcu::Vec3 nonShadowThreshold = tcu::computeFixedPointThreshold(nonShadowBits).swizzle(1,2,3); 1048 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1049 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler); 1050 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight()); 1051 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight()); 1052 int numFailedPixels; 1053 1054 gls::TextureTestUtil::sampleTexture(gls::TextureTestUtil::SurfaceAccess(reference, pixelFormat), effectiveView, texCoord, samplerParams); 1055 1056 numFailedPixels = gls::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView, 1057 texCoord, samplerParams, texComparePrecision, lodPrecision, nonShadowThreshold); 1058 1059 if (numFailedPixels > 0) 1060 { 1061 m_testCtx.getLog() << tcu::TestLog::Message 1062 << "Warning: Verification assuming high-quality PCF filtering failed." 1063 << tcu::TestLog::EndMessage; 1064 1065 numFailedPixels = gls::TextureTestUtil::computeTextureCompareDiff(renderedFrame, reference.getAccess(), errorMask.getAccess(), effectiveView, 1066 texCoord, samplerParams, lowQualityTexComparePrecision, lowQualityLodPrecision, nonShadowThreshold); 1067 1068 if (numFailedPixels > 0) 1069 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << tcu::TestLog::EndMessage; 1070 else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1071 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result"); 1072 } 1073 1074 if (numFailedPixels > 0) 1075 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1076 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1077 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame); 1078 if (numFailedPixels > 0) 1079 { 1080 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1081 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1082 } 1083 m_testCtx.getLog() << tcu::TestLog::EndImageSet; 1084 1085 return (numFailedPixels == 0); 1086 } 1087 1088 template <typename T> 1089 static inline T triQuadInterpolate (const T (&values)[4], float xFactor, float yFactor) 1090 { 1091 if (xFactor + yFactor < 1.0f) 1092 return values[0] + (values[2]-values[0])*xFactor + (values[1]-values[0])*yFactor; 1093 else 1094 return values[3] + (values[1]-values[3])*(1.0f-xFactor) + (values[2]-values[3])*(1.0f-yFactor); 1095 } 1096 1097 bool TextureBorderClampTest::verifyTextureGatherResult (const tcu::ConstPixelBufferAccess& renderedFrame, 1098 const float* texCoordArray, 1099 const gls::TextureTestUtil::ReferenceParams& samplerParams, 1100 const tcu::LookupPrecision& lookupPrecision) 1101 { 1102 const tcu::Vec2 texCoords[4] = 1103 { 1104 tcu::Vec2(texCoordArray[0], texCoordArray[1]), 1105 tcu::Vec2(texCoordArray[2], texCoordArray[3]), 1106 tcu::Vec2(texCoordArray[4], texCoordArray[5]), 1107 tcu::Vec2(texCoordArray[6], texCoordArray[7]), 1108 }; 1109 1110 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat(); 1111 const deUint8 fbColormask = gls::TextureTestUtil::getColorMask(pixelFormat); 1112 1113 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1114 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler); 1115 1116 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight()); 1117 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight()); 1118 int numFailedPixels = 0; 1119 1120 tcu::clear(errorMask.getAccess(), tcu::RGBA::green.toVec()); 1121 1122 for (int py = 0; py < reference.getHeight(); ++py) 1123 for (int px = 0; px < reference.getWidth(); ++px) 1124 { 1125 const tcu::Vec2 viewportCoord = (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight()); 1126 const tcu::Vec2 texCoord = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y()); 1127 const tcu::Vec4 referenceValue = effectiveView.gatherOffsets(samplerParams.sampler, texCoord.x(), texCoord.y(), 0, glu::getDefaultGatherOffsets()); 1128 const tcu::Vec4 referencePixel = referenceValue * samplerParams.colorScale + samplerParams.colorBias; 1129 const tcu::Vec4 resultPixel = renderedFrame.getPixel(px, py); 1130 const tcu::Vec4 resultValue = (resultPixel - samplerParams.colorBias) / samplerParams.colorScale; 1131 1132 reference.setPixel(px, py, gls::TextureTestUtil::toRGBAMasked(referenceValue, fbColormask)); 1133 1134 if (tcu::boolAny(tcu::logicalAnd(lookupPrecision.colorMask, 1135 tcu::greaterThan(tcu::absDiff(resultPixel, referencePixel), 1136 lookupPrecision.colorThreshold)))) 1137 { 1138 if (!tcu::isGatherOffsetsResultValid(effectiveView, samplerParams.sampler, lookupPrecision, texCoord, 0, glu::getDefaultGatherOffsets(), resultValue)) 1139 { 1140 errorMask.setPixel(px, py, tcu::RGBA::red); 1141 ++numFailedPixels; 1142 } 1143 } 1144 } 1145 1146 if (numFailedPixels > 0) 1147 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1148 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1149 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame); 1150 if (numFailedPixels > 0) 1151 { 1152 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1153 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1154 } 1155 m_testCtx.getLog() << tcu::TestLog::EndImageSet; 1156 1157 return (numFailedPixels == 0); 1158 } 1159 1160 bool TextureBorderClampTest::verifyTextureGatherCmpResult (const tcu::ConstPixelBufferAccess& renderedFrame, 1161 const float* texCoordArray, 1162 const gls::TextureTestUtil::ReferenceParams& samplerParams, 1163 const tcu::TexComparePrecision& texComparePrecision, 1164 const tcu::TexComparePrecision& lowQualityTexComparePrecision) 1165 { 1166 const tcu::Vec2 texCoords[4] = 1167 { 1168 tcu::Vec2(texCoordArray[0], texCoordArray[1]), 1169 tcu::Vec2(texCoordArray[2], texCoordArray[3]), 1170 tcu::Vec2(texCoordArray[4], texCoordArray[5]), 1171 tcu::Vec2(texCoordArray[6], texCoordArray[7]), 1172 }; 1173 1174 std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage; 1175 const tcu::Texture2DView effectiveView = tcu::getEffectiveTextureView(m_texture->getRefTexture(), srcLevelStorage, samplerParams.sampler); 1176 1177 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat(); 1178 const tcu::BVec4 colorMask = gls::TextureTestUtil::getCompareMask(pixelFormat); 1179 const deUint8 fbColormask = gls::TextureTestUtil::getColorMask(pixelFormat); 1180 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight()); 1181 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight()); 1182 int numFailedPixels = 0; 1183 bool lowQuality = false; 1184 1185 tcu::clear(errorMask.getAccess(), tcu::RGBA::green.toVec()); 1186 1187 for (int py = 0; py < reference.getHeight(); ++py) 1188 for (int px = 0; px < reference.getWidth(); ++px) 1189 { 1190 const tcu::Vec2 viewportCoord = (tcu::Vec2((float)px, (float)py) + tcu::Vec2(0.5f)) / tcu::Vec2((float)reference.getWidth(), (float)reference.getHeight()); 1191 const tcu::Vec2 texCoord = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y()); 1192 const float refZ = samplerParams.ref; 1193 const tcu::Vec4 referenceValue = effectiveView.gatherOffsetsCompare(samplerParams.sampler, refZ, texCoord.x(), texCoord.y(), glu::getDefaultGatherOffsets()); 1194 const tcu::Vec4 resultValue = renderedFrame.getPixel(px, py); 1195 1196 reference.setPixel(px, py, gls::TextureTestUtil::toRGBAMasked(referenceValue, fbColormask)); 1197 1198 if (tcu::boolAny(tcu::logicalAnd(colorMask, tcu::notEqual(referenceValue, resultValue)))) 1199 { 1200 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, texComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue)) 1201 { 1202 lowQuality = true; 1203 1204 // fall back to low quality verification 1205 if (!tcu::isGatherOffsetsCompareResultValid(effectiveView, samplerParams.sampler, lowQualityTexComparePrecision, texCoord, glu::getDefaultGatherOffsets(), refZ, resultValue)) 1206 { 1207 errorMask.setPixel(px, py, tcu::RGBA::red); 1208 ++numFailedPixels; 1209 } 1210 } 1211 } 1212 } 1213 1214 if (numFailedPixels > 0) 1215 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 1216 else if (lowQuality) 1217 { 1218 m_testCtx.getLog() << tcu::TestLog::Message << "Warning: Verification assuming high-quality PCF filtering failed." << tcu::TestLog::EndMessage; 1219 m_result.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality result"); 1220 } 1221 1222 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 1223 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame); 1224 if (numFailedPixels > 0) 1225 { 1226 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 1227 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 1228 } 1229 m_testCtx.getLog() << tcu::TestLog::EndImageSet; 1230 1231 return (numFailedPixels == 0); 1232 } 1233 1234 const glu::Texture2D* TextureBorderClampTest::getTexture (void) const 1235 { 1236 return m_texture.get(); 1237 } 1238 1239 deUint32 TextureBorderClampTest::getIterationSeed (const IterationConfig& config) const 1240 { 1241 tcu::SeedBuilder builder; 1242 builder << std::string(getName()) 1243 << m_iterationNdx 1244 << m_texFormat 1245 << config.minFilter << config.magFilter 1246 << m_texture->getRefTexture().getWidth() << m_texture->getRefTexture().getHeight(); 1247 return builder.get(); 1248 } 1249 1250 gls::TextureTestUtil::ReferenceParams TextureBorderClampTest::genSamplerParams (const IterationConfig& config) const 1251 { 1252 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(m_texture->getRefTexture().getFormat(), m_sampleMode); 1253 gls::TextureTestUtil::ReferenceParams refParams (gls::TextureTestUtil::TEXTURETYPE_2D); 1254 1255 refParams.sampler = glu::mapGLSampler(config.sWrapMode, config.tWrapMode, config.minFilter, config.magFilter); 1256 refParams.sampler.borderColor = config.borderColor; 1257 refParams.sampler.compare = (!m_useShadowSampler) ? (tcu::Sampler::COMPAREMODE_NONE) : (glu::mapGLCompareFunc(config.compareMode)); 1258 refParams.sampler.depthStencilMode = m_sampleMode; 1259 refParams.lodMode = gls::TextureTestUtil::LODMODE_EXACT; 1260 refParams.samplerType = (!m_useShadowSampler) ? (gls::TextureTestUtil::getSamplerType(texFormat)) : (gls::TextureTestUtil::SAMPLERTYPE_SHADOW); 1261 refParams.colorScale = config.lookupScale; 1262 refParams.colorBias = config.lookupBias; 1263 refParams.ref = config.compareRef; 1264 1265 // compare can only be used with depth textures 1266 if (!isDepthFormat(m_texFormat, m_sampleMode)) 1267 DE_ASSERT(refParams.sampler.compare == tcu::Sampler::COMPAREMODE_NONE); 1268 1269 // sampler type must match compare mode 1270 DE_ASSERT(m_useShadowSampler == (config.compareMode != GL_NONE)); 1271 1272 // in gather, weird mapping is most likely an error 1273 if (m_samplingFunction == SAMPLE_GATHER) 1274 { 1275 DE_ASSERT(refParams.colorScale == tcu::Vec4(refParams.colorScale.x())); 1276 DE_ASSERT(refParams.colorBias == tcu::Vec4(refParams.colorBias.x())); 1277 } 1278 1279 return refParams; 1280 } 1281 1282 glu::ShaderProgram* TextureBorderClampTest::genGatherProgram (void) const 1283 { 1284 const char* const vtxSource = "#version 310 es\n" 1285 "in highp vec4 a_position;\n" 1286 "in highp vec2 a_texcoord;\n" 1287 "out highp vec2 v_texcoord;\n" 1288 "void main()\n" 1289 "{\n" 1290 " gl_Position = a_position;\n" 1291 " v_texcoord = a_texcoord;\n" 1292 "}\n"; 1293 const char* samplerType; 1294 const char* lookup; 1295 std::ostringstream fragSource; 1296 1297 if (m_useShadowSampler) 1298 { 1299 samplerType = "sampler2DShadow"; 1300 lookup = "textureGather(u_sampler, v_texcoord, u_ref)"; 1301 } 1302 else 1303 { 1304 switch (m_channelClass) 1305 { 1306 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 1307 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 1308 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 1309 samplerType = "sampler2D"; 1310 lookup = "textureGather(u_sampler, v_texcoord)"; 1311 break; 1312 1313 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 1314 samplerType = "isampler2D"; 1315 lookup = "vec4(textureGather(u_sampler, v_texcoord))"; 1316 break; 1317 1318 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 1319 samplerType = "usampler2D"; 1320 lookup = "vec4(textureGather(u_sampler, v_texcoord))"; 1321 break; 1322 1323 default: 1324 samplerType = ""; 1325 lookup = ""; 1326 DE_ASSERT(false); 1327 } 1328 } 1329 1330 fragSource << "#version 310 es\n" 1331 "uniform highp " << samplerType << " u_sampler;\n" 1332 "uniform highp vec4 u_colorScale;\n" 1333 "uniform highp vec4 u_colorBias;\n" 1334 << ((m_useShadowSampler) ? ("uniform highp float u_ref;\n") : ("")) 1335 << "in highp vec2 v_texcoord;\n" 1336 "layout(location=0) out highp vec4 o_color;\n" 1337 "void main()\n" 1338 "{\n" 1339 " o_color = " << lookup << " * u_colorScale + u_colorBias;\n" 1340 "}\n"; 1341 1342 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vtxSource) << glu::FragmentSource(fragSource.str())); 1343 } 1344 1345 class TextureBorderClampFormatCase : public TextureBorderClampTest 1346 { 1347 public: 1348 TextureBorderClampFormatCase (Context& context, 1349 const char* name, 1350 const char* description, 1351 deUint32 texFormat, 1352 tcu::Sampler::DepthStencilMode mode, 1353 StateType stateType, 1354 SizeType sizeType, 1355 deUint32 filter, 1356 SamplingFunction samplingFunction); 1357 1358 private: 1359 void init (void); 1360 1361 int getNumIterations (void) const; 1362 IterationConfig getIteration (int ndx) const; 1363 1364 const SizeType m_sizeType; 1365 const deUint32 m_filter; 1366 1367 std::vector<IterationConfig> m_iterations; 1368 }; 1369 1370 1371 TextureBorderClampFormatCase::TextureBorderClampFormatCase (Context& context, 1372 const char* name, 1373 const char* description, 1374 deUint32 texFormat, 1375 tcu::Sampler::DepthStencilMode mode, 1376 StateType stateType, 1377 SizeType sizeType, 1378 deUint32 filter, 1379 SamplingFunction samplingFunction) 1380 : TextureBorderClampTest(context, 1381 name, 1382 description, 1383 texFormat, 1384 mode, 1385 stateType, 1386 (sizeType == SIZE_POT) ? (32) : (17), 1387 (sizeType == SIZE_POT) ? (16) : (31), 1388 samplingFunction) 1389 , m_sizeType (sizeType) 1390 , m_filter (filter) 1391 { 1392 if (m_sizeType == SIZE_POT) 1393 DE_ASSERT(deIsPowerOfTwo32(m_texWidth) && deIsPowerOfTwo32(m_texHeight)); 1394 else 1395 DE_ASSERT(!deIsPowerOfTwo32(m_texWidth) && !deIsPowerOfTwo32(m_texHeight)); 1396 1397 if (glu::isCompressedFormat(texFormat)) 1398 { 1399 const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(texFormat); 1400 const tcu::IVec3 blockPixelSize = tcu::getBlockPixelSize(compressedFormat); 1401 1402 // is (not) multiple of a block size 1403 if (m_sizeType == SIZE_POT) 1404 DE_ASSERT((m_texWidth % blockPixelSize.x()) == 0 && (m_texHeight % blockPixelSize.y()) == 0); 1405 else 1406 DE_ASSERT((m_texWidth % blockPixelSize.x()) != 0 && (m_texHeight % blockPixelSize.y()) != 0); 1407 1408 DE_UNREF(blockPixelSize); 1409 } 1410 } 1411 1412 void TextureBorderClampFormatCase::init (void) 1413 { 1414 TextureBorderClampTest::init(); 1415 1416 // \note TextureBorderClampTest::init() creates texture 1417 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode); 1418 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat); 1419 1420 // iterations 1421 1422 { 1423 IterationConfig iteration; 1424 iteration.p0 = tcu::Vec2(-1.5f, -3.0f); 1425 iteration.p1 = tcu::Vec2( 1.5f, 2.5f); 1426 iteration.borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.3f, 0.7f, 0.2f, 0.5f)); 1427 m_iterations.push_back(iteration); 1428 } 1429 { 1430 IterationConfig iteration; 1431 iteration.p0 = tcu::Vec2(-0.5f, 0.75f); 1432 iteration.p1 = tcu::Vec2(0.25f, 1.25f); 1433 iteration.borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.9f, 0.2f, 0.4f, 0.6f)); 1434 m_iterations.push_back(iteration); 1435 } 1436 1437 // common parameters 1438 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx) 1439 { 1440 IterationConfig& iteration = m_iterations[ndx]; 1441 1442 if (m_samplingFunction == SAMPLE_GATHER) 1443 { 1444 iteration.lookupScale = tcu::Vec4(texFormatInfo.lookupScale.x()); 1445 iteration.lookupBias = tcu::Vec4(texFormatInfo.lookupBias.x()); 1446 } 1447 else 1448 { 1449 iteration.lookupScale = texFormatInfo.lookupScale; 1450 iteration.lookupBias = texFormatInfo.lookupBias; 1451 } 1452 1453 iteration.minFilter = m_filter; 1454 iteration.magFilter = m_filter; 1455 iteration.sWrapMode = GL_CLAMP_TO_BORDER; 1456 iteration.tWrapMode = GL_CLAMP_TO_BORDER; 1457 iteration.compareMode = GL_NONE; 1458 iteration.compareRef = 0.0f; 1459 } 1460 } 1461 1462 int TextureBorderClampFormatCase::getNumIterations (void) const 1463 { 1464 return (int)m_iterations.size(); 1465 } 1466 1467 TextureBorderClampTest::IterationConfig TextureBorderClampFormatCase::getIteration (int ndx) const 1468 { 1469 return m_iterations[ndx]; 1470 } 1471 1472 class TextureBorderClampRangeClampCase : public TextureBorderClampTest 1473 { 1474 public: 1475 TextureBorderClampRangeClampCase (Context& context, 1476 const char* name, 1477 const char* description, 1478 deUint32 texFormat, 1479 tcu::Sampler::DepthStencilMode mode, 1480 deUint32 filter); 1481 1482 private: 1483 void init (void); 1484 1485 int getNumIterations (void) const; 1486 IterationConfig getIteration (int ndx) const; 1487 1488 const deUint32 m_filter; 1489 std::vector<IterationConfig> m_iterations; 1490 }; 1491 1492 TextureBorderClampRangeClampCase::TextureBorderClampRangeClampCase (Context& context, 1493 const char* name, 1494 const char* description, 1495 deUint32 texFormat, 1496 tcu::Sampler::DepthStencilMode mode, 1497 deUint32 filter) 1498 : TextureBorderClampTest(context, name, description, texFormat, mode, TextureBorderClampTest::STATE_TEXTURE_PARAM, 8, 32, SAMPLE_FILTER) 1499 , m_filter (filter) 1500 { 1501 } 1502 1503 void TextureBorderClampRangeClampCase::init (void) 1504 { 1505 TextureBorderClampTest::init(); 1506 1507 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode); 1508 const bool isDepth = isDepthFormat(m_texFormat, m_sampleMode); 1509 const bool isFloat = m_channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT; 1510 const bool isFixed = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT; 1511 const bool isPureInteger = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER; 1512 1513 if (isDepth || isFloat) 1514 { 1515 // infinities are commonly used values on depth/float borders 1516 { 1517 IterationConfig iteration; 1518 iteration.p0 = tcu::Vec2(-1.2f, -3.0f); 1519 iteration.p1 = tcu::Vec2( 1.2f, 2.5f); 1520 iteration.borderColor = rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity())); 1521 iteration.lookupScale = tcu::Vec4(0.5f); // scale & bias to [0.25, 0.5] range to make out-of-range values visible 1522 iteration.lookupBias = tcu::Vec4(0.25f); 1523 iteration.description = "border value infinity"; 1524 m_iterations.push_back(iteration); 1525 } 1526 { 1527 IterationConfig iteration; 1528 iteration.p0 = tcu::Vec2(-0.25f, -0.75f); 1529 iteration.p1 = tcu::Vec2( 2.25f, 1.25f); 1530 iteration.borderColor = rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity())); 1531 iteration.lookupScale = tcu::Vec4(0.5f); 1532 iteration.lookupBias = tcu::Vec4(0.25f); 1533 iteration.description = "border value negative infinity"; 1534 m_iterations.push_back(iteration); 1535 } 1536 } 1537 else if (isPureInteger) 1538 { 1539 const tcu::IVec4 numBits = tcu::getTextureFormatBitDepth(texFormat); 1540 const bool isSigned = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER; 1541 1542 // can't overflow 32bit integers with 32bit integers 1543 for (int ndx = 0; ndx < 4; ++ndx) 1544 DE_ASSERT(numBits[ndx] == 0 || numBits[ndx] == 8 || numBits[ndx] == 16); 1545 1546 const tcu::IVec4 minValue = getNBitIntegerVec4MinValue(isSigned, numBits); 1547 const tcu::IVec4 maxValue = getNBitIntegerVec4MaxValue(isSigned, numBits); 1548 const tcu::IVec4 valueRange = maxValue - minValue; 1549 const tcu::IVec4 divSafeRange ((valueRange[0]==0) ? (1) : (valueRange[0]), 1550 (valueRange[1]==0) ? (1) : (valueRange[1]), 1551 (valueRange[2]==0) ? (1) : (valueRange[2]), 1552 (valueRange[3]==0) ? (1) : (valueRange[3])); 1553 1554 // format max 1555 { 1556 const tcu::IVec4 value = maxValue + tcu::IVec4(1); 1557 1558 IterationConfig iteration; 1559 iteration.p0 = tcu::Vec2(-1.2f, -3.0f); 1560 iteration.p1 = tcu::Vec2( 1.2f, 2.5f); 1561 iteration.borderColor = (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>())); 1562 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>(); 1563 iteration.lookupBias = (isSigned) ? (tcu::Vec4(0.5f)) : (tcu::Vec4(0.25f)); 1564 iteration.description = "border values one larger than maximum"; 1565 m_iterations.push_back(iteration); 1566 } 1567 // format min 1568 if (isSigned) 1569 { 1570 const tcu::IVec4 value = minValue - tcu::IVec4(1); 1571 1572 IterationConfig iteration; 1573 iteration.p0 = tcu::Vec2(-0.25f, -0.75f); 1574 iteration.p1 = tcu::Vec2( 2.25f, 1.25f); 1575 iteration.borderColor = rr::GenericVec4(value); 1576 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>(); 1577 iteration.lookupBias = tcu::Vec4(0.5f); 1578 iteration.description = "border values one less than minimum"; 1579 m_iterations.push_back(iteration); 1580 } 1581 // (u)int32 max 1582 { 1583 const tcu::IVec4 value = (isSigned) ? (tcu::IVec4(std::numeric_limits<deInt32>::max())) : (tcu::IVec4(std::numeric_limits<deUint32>::max())); 1584 1585 IterationConfig iteration; 1586 iteration.p0 = tcu::Vec2(-1.6f, -2.1f); 1587 iteration.p1 = tcu::Vec2( 1.2f, 3.5f); 1588 iteration.borderColor = (isSigned) ? (rr::GenericVec4(value)) : (rr::GenericVec4(value.cast<deUint32>())); 1589 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>(); 1590 iteration.lookupBias = tcu::Vec4(0.25f); 1591 iteration.description = "border values 32-bit maximum"; 1592 m_iterations.push_back(iteration); 1593 } 1594 // int32 min 1595 if (isSigned) 1596 { 1597 const tcu::IVec4 value = tcu::IVec4(std::numeric_limits<deInt32>::min()); 1598 1599 IterationConfig iteration; 1600 iteration.p0 = tcu::Vec2(-2.6f, -4.0f); 1601 iteration.p1 = tcu::Vec2( 1.1f, 1.5f); 1602 iteration.borderColor = rr::GenericVec4(value); 1603 iteration.lookupScale = tcu::Vec4(0.5f) / divSafeRange.cast<float>(); 1604 iteration.lookupBias = tcu::Vec4(0.25f); 1605 iteration.description = "border values 0"; 1606 m_iterations.push_back(iteration); 1607 } 1608 } 1609 else if (isFixed) 1610 { 1611 const bool isSigned = m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;; 1612 const tcu::Vec4 lookupBias = (isSigned) ? (tcu::Vec4(0.5f)) : (tcu::Vec4(0.25f)); // scale & bias to [0.25, 0.5] range to make out-of-range values visible 1613 const tcu::Vec4 lookupScale = (isSigned) ? (tcu::Vec4(0.25f)) : (tcu::Vec4(0.5f)); 1614 1615 { 1616 IterationConfig iteration; 1617 iteration.p0 = tcu::Vec2(-1.2f, -3.0f); 1618 iteration.p1 = tcu::Vec2( 1.2f, 2.5f); 1619 iteration.borderColor = mapToFormatColorUnits(texFormat, tcu::Vec4(1.1f, 1.3f, 2.2f, 1.3f)); 1620 iteration.lookupScale = lookupScale; 1621 iteration.lookupBias = lookupBias; 1622 iteration.description = "border values larger than maximum"; 1623 m_iterations.push_back(iteration); 1624 } 1625 { 1626 IterationConfig iteration; 1627 iteration.p0 = tcu::Vec2(-0.25f, -0.75f); 1628 iteration.p1 = tcu::Vec2( 2.25f, 1.25f); 1629 iteration.borderColor = mapToFormatColorUnits(texFormat, tcu::Vec4(-0.2f, -0.9f, -2.4f, -0.6f)); 1630 iteration.lookupScale = lookupScale; 1631 iteration.lookupBias = lookupBias; 1632 iteration.description = "border values less than minimum"; 1633 m_iterations.push_back(iteration); 1634 } 1635 } 1636 else 1637 DE_ASSERT(false); 1638 1639 // common parameters 1640 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx) 1641 { 1642 IterationConfig& iteration = m_iterations[ndx]; 1643 1644 iteration.minFilter = m_filter; 1645 iteration.magFilter = m_filter; 1646 iteration.sWrapMode = GL_CLAMP_TO_BORDER; 1647 iteration.tWrapMode = GL_CLAMP_TO_BORDER; 1648 iteration.compareMode = GL_NONE; 1649 iteration.compareRef = 0.0f; 1650 } 1651 } 1652 1653 int TextureBorderClampRangeClampCase::getNumIterations (void) const 1654 { 1655 return (int)m_iterations.size(); 1656 } 1657 1658 TextureBorderClampTest::IterationConfig TextureBorderClampRangeClampCase::getIteration (int ndx) const 1659 { 1660 return m_iterations[ndx]; 1661 } 1662 1663 class TextureBorderClampPerAxisCase2D : public TextureBorderClampTest 1664 { 1665 public: 1666 TextureBorderClampPerAxisCase2D (Context& context, 1667 const char* name, 1668 const char* description, 1669 deUint32 texFormat, 1670 tcu::Sampler::DepthStencilMode mode, 1671 SizeType sizeType, 1672 deUint32 filter, 1673 deUint32 texSWrap, 1674 deUint32 texTWrap, 1675 SamplingFunction samplingFunction); 1676 1677 private: 1678 void init (void); 1679 1680 int getNumIterations (void) const; 1681 IterationConfig getIteration (int ndx) const; 1682 1683 const deUint32 m_texSWrap; 1684 const deUint32 m_texTWrap; 1685 const deUint32 m_filter; 1686 1687 std::vector<IterationConfig> m_iterations; 1688 }; 1689 1690 TextureBorderClampPerAxisCase2D::TextureBorderClampPerAxisCase2D (Context& context, 1691 const char* name, 1692 const char* description, 1693 deUint32 texFormat, 1694 tcu::Sampler::DepthStencilMode mode, 1695 SizeType sizeType, 1696 deUint32 filter, 1697 deUint32 texSWrap, 1698 deUint32 texTWrap, 1699 SamplingFunction samplingFunction) 1700 : TextureBorderClampTest(context, 1701 name, 1702 description, 1703 texFormat, 1704 mode, 1705 TextureBorderClampTest::STATE_TEXTURE_PARAM, 1706 (sizeType == SIZE_POT) ? (16) : (7), 1707 (sizeType == SIZE_POT) ? (8) : (9), 1708 samplingFunction) 1709 , m_texSWrap (texSWrap) 1710 , m_texTWrap (texTWrap) 1711 , m_filter (filter) 1712 { 1713 } 1714 1715 void TextureBorderClampPerAxisCase2D::init (void) 1716 { 1717 TextureBorderClampTest::init(); 1718 1719 // \note TextureBorderClampTest::init() creates texture 1720 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode); 1721 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat); 1722 1723 IterationConfig iteration; 1724 iteration.p0 = tcu::Vec2(-0.25f, -0.75f); 1725 iteration.p1 = tcu::Vec2( 2.25f, 1.25f); 1726 iteration.borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.4f, 0.9f, 0.1f, 0.2f)); 1727 1728 if (m_samplingFunction == SAMPLE_GATHER) 1729 { 1730 iteration.lookupScale = tcu::Vec4(texFormatInfo.lookupScale.x()); 1731 iteration.lookupBias = tcu::Vec4(texFormatInfo.lookupBias.x()); 1732 } 1733 else 1734 { 1735 iteration.lookupScale = texFormatInfo.lookupScale; 1736 iteration.lookupBias = texFormatInfo.lookupBias; 1737 } 1738 1739 iteration.minFilter = m_filter; 1740 iteration.magFilter = m_filter; 1741 iteration.sWrapMode = m_texSWrap; 1742 iteration.tWrapMode = m_texTWrap; 1743 iteration.compareMode = GL_NONE; 1744 iteration.compareRef = 0.0f; 1745 1746 m_iterations.push_back(iteration); 1747 } 1748 1749 int TextureBorderClampPerAxisCase2D::getNumIterations (void) const 1750 { 1751 return (int)m_iterations.size(); 1752 } 1753 1754 TextureBorderClampTest::IterationConfig TextureBorderClampPerAxisCase2D::getIteration (int ndx) const 1755 { 1756 return m_iterations[ndx]; 1757 } 1758 1759 class TextureBorderClampDepthCompareCase : public TextureBorderClampTest 1760 { 1761 public: 1762 TextureBorderClampDepthCompareCase (Context& context, 1763 const char* name, 1764 const char* description, 1765 deUint32 texFormat, 1766 SizeType sizeType, 1767 deUint32 filter, 1768 SamplingFunction samplingFunction); 1769 1770 private: 1771 void init (void); 1772 1773 int getNumIterations (void) const; 1774 IterationConfig getIteration (int ndx) const; 1775 1776 const deUint32 m_filter; 1777 std::vector<IterationConfig> m_iterations; 1778 }; 1779 1780 TextureBorderClampDepthCompareCase::TextureBorderClampDepthCompareCase (Context& context, 1781 const char* name, 1782 const char* description, 1783 deUint32 texFormat, 1784 SizeType sizeType, 1785 deUint32 filter, 1786 SamplingFunction samplingFunction) 1787 : TextureBorderClampTest(context, 1788 name, 1789 description, 1790 texFormat, 1791 tcu::Sampler::MODE_DEPTH, 1792 TextureBorderClampTest::STATE_TEXTURE_PARAM, 1793 (sizeType == SIZE_POT) ? (32) : (13), 1794 (sizeType == SIZE_POT) ? (16) : (17), 1795 samplingFunction, 1796 FLAG_USE_SHADOW_SAMPLER) 1797 , m_filter (filter) 1798 { 1799 } 1800 1801 void TextureBorderClampDepthCompareCase::init (void) 1802 { 1803 TextureBorderClampTest::init(); 1804 1805 // 0.5 <= 0.7 1806 { 1807 IterationConfig iteration; 1808 iteration.p0 = tcu::Vec2(-0.15f, -0.35f); 1809 iteration.p1 = tcu::Vec2( 1.25f, 1.1f); 1810 iteration.borderColor = rr::GenericVec4(tcu::Vec4(0.7f, 0.0f, 0.0f, 0.0f)); 1811 iteration.description = "Border color in [0, 1] range"; 1812 iteration.compareMode = GL_LEQUAL; 1813 iteration.compareRef = 0.5f; 1814 m_iterations.push_back(iteration); 1815 } 1816 1817 // 1.5 <= 1.0 1818 { 1819 IterationConfig iteration; 1820 iteration.p0 = tcu::Vec2(-0.15f, -0.35f); 1821 iteration.p1 = tcu::Vec2( 1.25f, 1.1f); 1822 iteration.borderColor = rr::GenericVec4(tcu::Vec4(1.5f, 0.0f, 0.0f, 0.0f)); 1823 iteration.description = "Border color > 1, should be clamped"; 1824 iteration.compareMode = GL_LEQUAL; 1825 iteration.compareRef = 1.0f; 1826 m_iterations.push_back(iteration); 1827 } 1828 1829 // -0.5 >= 0.0 1830 { 1831 IterationConfig iteration; 1832 iteration.p0 = tcu::Vec2(-0.15f, -0.35f); 1833 iteration.p1 = tcu::Vec2( 1.25f, 1.1f); 1834 iteration.borderColor = rr::GenericVec4(tcu::Vec4(-0.5f, 0.0f, 0.0f, 0.0f)); 1835 iteration.description = "Border color < 0, should be clamped"; 1836 iteration.compareMode = GL_GEQUAL; 1837 iteration.compareRef = 0.0f; 1838 m_iterations.push_back(iteration); 1839 } 1840 1841 // inf < 1.25 1842 { 1843 IterationConfig iteration; 1844 iteration.p0 = tcu::Vec2(-0.15f, -0.35f); 1845 iteration.p1 = tcu::Vec2( 1.25f, 1.1f); 1846 iteration.borderColor = rr::GenericVec4(tcu::Vec4(std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f)); 1847 iteration.description = "Border color == inf, should be clamped; ref > 1"; 1848 iteration.compareMode = GL_LESS; 1849 iteration.compareRef = 1.25f; 1850 m_iterations.push_back(iteration); 1851 } 1852 1853 // -inf > -0.5 1854 { 1855 IterationConfig iteration; 1856 iteration.p0 = tcu::Vec2(-0.15f, -0.35f); 1857 iteration.p1 = tcu::Vec2( 1.25f, 1.1f); 1858 iteration.borderColor = rr::GenericVec4(tcu::Vec4(-std::numeric_limits<float>::infinity(), 0.0f, 0.0f, 0.0f)); 1859 iteration.description = "Border color == inf, should be clamped; ref < 0"; 1860 iteration.compareMode = GL_GREATER; 1861 iteration.compareRef = -0.5f; 1862 m_iterations.push_back(iteration); 1863 } 1864 1865 // common parameters 1866 for (int ndx = 0; ndx < (int)m_iterations.size(); ++ndx) 1867 { 1868 IterationConfig& iteration = m_iterations[ndx]; 1869 1870 iteration.lookupScale = tcu::Vec4(1.0); 1871 iteration.lookupBias = tcu::Vec4(0.0); 1872 iteration.minFilter = m_filter; 1873 iteration.magFilter = m_filter; 1874 iteration.sWrapMode = GL_CLAMP_TO_BORDER; 1875 iteration.tWrapMode = GL_CLAMP_TO_BORDER; 1876 } 1877 } 1878 1879 int TextureBorderClampDepthCompareCase::getNumIterations (void) const 1880 { 1881 return (int)m_iterations.size(); 1882 } 1883 1884 TextureBorderClampTest::IterationConfig TextureBorderClampDepthCompareCase::getIteration (int ndx) const 1885 { 1886 return m_iterations[ndx]; 1887 } 1888 1889 class TextureBorderClampUnusedChannelCase : public TextureBorderClampTest 1890 { 1891 public: 1892 TextureBorderClampUnusedChannelCase (Context& context, 1893 const char* name, 1894 const char* description, 1895 deUint32 texFormat, 1896 tcu::Sampler::DepthStencilMode depthStencilMode); 1897 1898 private: 1899 void init (void); 1900 1901 int getNumIterations (void) const; 1902 IterationConfig getIteration (int ndx) const; 1903 1904 std::vector<IterationConfig> m_iterations; 1905 }; 1906 1907 TextureBorderClampUnusedChannelCase::TextureBorderClampUnusedChannelCase (Context& context, 1908 const char* name, 1909 const char* description, 1910 deUint32 texFormat, 1911 tcu::Sampler::DepthStencilMode depthStencilMode) 1912 : TextureBorderClampTest(context, 1913 name, 1914 description, 1915 texFormat, 1916 depthStencilMode, 1917 TextureBorderClampTest::STATE_TEXTURE_PARAM, 1918 8, 1919 8, 1920 SAMPLE_FILTER) 1921 { 1922 } 1923 1924 static rr::GenericVec4 selectComponents (const rr::GenericVec4& trueComponents, const rr::GenericVec4& falseComponents, const tcu::BVec4& m) 1925 { 1926 return rr::GenericVec4(tcu::select(trueComponents.get<deUint32>(), falseComponents.get<deUint32>(), m)); 1927 } 1928 1929 void TextureBorderClampUnusedChannelCase::init (void) 1930 { 1931 TextureBorderClampTest::init(); 1932 1933 // \note TextureBorderClampTest::init() creates texture 1934 const tcu::TextureFormat texFormat = tcu::getEffectiveDepthStencilTextureFormat(getTexture()->getRefTexture().getFormat(), m_sampleMode); 1935 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat); 1936 const tcu::BVec4 channelMask = tcu::getTextureFormatChannelMask(texFormat); 1937 const float maxChannelValue = (channelMask[0]) ? (texFormatInfo.valueMax[0]) 1938 : (channelMask[1]) ? (texFormatInfo.valueMax[1]) 1939 : (channelMask[2]) ? (texFormatInfo.valueMax[2]) 1940 : (texFormatInfo.valueMax[3]); 1941 1942 const rr::GenericVec4 effectiveColors = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.6f)); 1943 rr::GenericVec4 nonEffectiveColors; 1944 1945 switch (m_channelClass) 1946 { 1947 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 1948 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 1949 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 1950 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f)); 1951 break; 1952 1953 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 1954 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deInt32>()); 1955 break; 1956 1957 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 1958 nonEffectiveColors = rr::GenericVec4(tcu::Vec4(maxChannelValue * 0.8f).cast<deUint32>()); 1959 break; 1960 default: 1961 DE_ASSERT(false); 1962 } 1963 1964 IterationConfig iteration; 1965 iteration.p0 = tcu::Vec2(-0.25f, -0.75f); 1966 iteration.p1 = tcu::Vec2( 2.25f, 1.25f); 1967 iteration.borderColor = selectComponents(effectiveColors, nonEffectiveColors, channelMask); 1968 iteration.lookupScale = texFormatInfo.lookupScale; 1969 iteration.lookupBias = texFormatInfo.lookupBias; 1970 iteration.minFilter = GL_NEAREST; 1971 iteration.magFilter = GL_NEAREST; 1972 iteration.sWrapMode = GL_CLAMP_TO_BORDER; 1973 iteration.tWrapMode = GL_CLAMP_TO_BORDER; 1974 iteration.compareMode = GL_NONE; 1975 iteration.compareRef = 0.0f; 1976 iteration.description = "Setting values to unused border color components"; 1977 1978 m_iterations.push_back(iteration); 1979 } 1980 1981 int TextureBorderClampUnusedChannelCase::getNumIterations (void) const 1982 { 1983 return (int)m_iterations.size(); 1984 } 1985 1986 TextureBorderClampTest::IterationConfig TextureBorderClampUnusedChannelCase::getIteration (int ndx) const 1987 { 1988 return m_iterations[ndx]; 1989 } 1990 1991 class TextureBorderClampPerAxisCase3D : public TestCase 1992 { 1993 public: 1994 TextureBorderClampPerAxisCase3D (Context& context, 1995 const char* name, 1996 const char* description, 1997 deUint32 texFormat, 1998 SizeType size, 1999 deUint32 filter, 2000 deUint32 sWrap, 2001 deUint32 tWrap, 2002 deUint32 rWrap); 2003 2004 private: 2005 void init (void); 2006 void deinit (void); 2007 IterateResult iterate (void); 2008 2009 void renderTo (tcu::Surface& surface, 2010 const gls::TextureTestUtil::ReferenceParams& samplerParams); 2011 2012 void logParams (const gls::TextureTestUtil::ReferenceParams& samplerParams); 2013 2014 void verifyImage (const tcu::Surface& image, 2015 const gls::TextureTestUtil::ReferenceParams& samplerParams); 2016 2017 gls::TextureTestUtil::ReferenceParams getSamplerParams (void) const; 2018 deUint32 getCaseSeed (void) const; 2019 2020 enum 2021 { 2022 VIEWPORT_WIDTH = 128, 2023 VIEWPORT_HEIGHT = 128, 2024 }; 2025 2026 const deUint32 m_texFormat; 2027 const tcu::TextureChannelClass m_channelClass; 2028 const tcu::IVec3 m_size; 2029 const deUint32 m_filter; 2030 const deUint32 m_sWrap; 2031 const deUint32 m_tWrap; 2032 const deUint32 m_rWrap; 2033 2034 de::MovePtr<glu::Texture3D> m_texture; 2035 de::MovePtr<gls::TextureTestUtil::TextureRenderer> m_renderer; 2036 2037 rr::GenericVec4 m_borderColor; 2038 std::vector<float> m_texCoords; 2039 tcu::Vec4 m_lookupScale; 2040 tcu::Vec4 m_lookupBias; 2041 }; 2042 2043 TextureBorderClampPerAxisCase3D::TextureBorderClampPerAxisCase3D (Context& context, 2044 const char* name, 2045 const char* description, 2046 deUint32 texFormat, 2047 SizeType size, 2048 deUint32 filter, 2049 deUint32 sWrap, 2050 deUint32 tWrap, 2051 deUint32 rWrap) 2052 : TestCase (context, name, description) 2053 , m_texFormat (texFormat) 2054 , m_channelClass (getFormatChannelClass(texFormat, tcu::Sampler::MODE_LAST)) 2055 , m_size ((size == SIZE_POT) ? (tcu::IVec3(8, 16, 4)) : (tcu::IVec3(13, 5, 7))) 2056 , m_filter (filter) 2057 , m_sWrap (sWrap) 2058 , m_tWrap (tWrap) 2059 , m_rWrap (rWrap) 2060 { 2061 } 2062 2063 void TextureBorderClampPerAxisCase3D::init (void) 2064 { 2065 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_border_clamp")) 2066 throw tcu::NotSupportedError("Test requires GL_EXT_texture_border_clamp extension"); 2067 2068 if (glu::isCompressedFormat(m_texFormat) && 2069 tcu::isAstcFormat(glu::mapGLCompressedTexFormat(m_texFormat)) && 2070 !m_context.getContextInfo().isExtensionSupported("GL_KHR_texture_compression_astc_ldr")) 2071 { 2072 throw tcu::NotSupportedError("Test requires GL_KHR_texture_compression_astc_ldr extension"); 2073 } 2074 if (m_texFormat == GL_BGRA && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_format_BGRA8888")) 2075 throw tcu::NotSupportedError("Test requires GL_EXT_texture_format_BGRA8888 extension"); 2076 if (m_context.getRenderTarget().getWidth() < VIEWPORT_WIDTH || 2077 m_context.getRenderTarget().getHeight() < VIEWPORT_HEIGHT) 2078 { 2079 throw tcu::NotSupportedError("Test requires " + de::toString<int>(VIEWPORT_WIDTH) + "x" + de::toString<int>(VIEWPORT_HEIGHT) + " viewport"); 2080 } 2081 2082 // resources 2083 m_texture = genDummyTexture<glu::Texture3D>(m_context.getRenderContext(), m_context.getContextInfo(), m_texFormat, m_size); 2084 m_renderer = de::MovePtr<gls::TextureTestUtil::TextureRenderer>(new gls::TextureTestUtil::TextureRenderer(m_context.getRenderContext(), m_testCtx.getLog(), glu::GLSL_VERSION_310_ES, glu::PRECISION_HIGHP)); 2085 2086 // texture info 2087 m_testCtx.getLog() << tcu::TestLog::Message 2088 << "Created 3D texture with format " << ((glu::isCompressedFormat(m_texFormat)) ? (glu::getCompressedTexFormatName(m_texFormat)) : (glu::getPixelFormatName(m_texFormat))) 2089 << ", size (" << m_texture->getRefTexture().getWidth() << ", " << m_texture->getRefTexture().getHeight() << ", " << m_texture->getRefTexture().getDepth() << ")\n" 2090 << tcu::TestLog::EndMessage; 2091 2092 // tex coord 2093 { 2094 m_testCtx.getLog() << tcu::TestLog::Message 2095 << "Setting tex coords bottom-left: (-1, -1, -1.5), top-right (2, 2, 2.5)\n" 2096 << tcu::TestLog::EndMessage; 2097 2098 m_texCoords.resize(4*3); 2099 2100 m_texCoords[0] = -1.0f; m_texCoords[ 1] = -1.0f; m_texCoords[ 2] = -1.5f; 2101 m_texCoords[3] = -1.0f; m_texCoords[ 4] = 2.0f; m_texCoords[ 5] = 0.5f; 2102 m_texCoords[6] = 2.0f; m_texCoords[ 7] = -1.0f; m_texCoords[ 8] = 0.5f; 2103 m_texCoords[9] = 2.0f; m_texCoords[10] = 2.0f; m_texCoords[11] = 2.5f; 2104 } 2105 2106 // set render params 2107 { 2108 const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat(); 2109 const tcu::TextureFormatInfo texFormatInfo = tcu::getTextureFormatInfo(texFormat); 2110 2111 m_borderColor = mapToFormatColorRepresentable(texFormat, tcu::Vec4(0.2f, 0.6f, 0.9f, 0.4f)); 2112 2113 m_lookupScale = texFormatInfo.lookupScale; 2114 m_lookupBias = texFormatInfo.lookupBias; 2115 } 2116 } 2117 2118 void TextureBorderClampPerAxisCase3D::deinit (void) 2119 { 2120 m_texture.clear(); 2121 m_renderer.clear(); 2122 } 2123 2124 TextureBorderClampPerAxisCase3D::IterateResult TextureBorderClampPerAxisCase3D::iterate (void) 2125 { 2126 tcu::Surface renderedFrame (VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 2127 const gls::TextureTestUtil::ReferenceParams samplerParams = getSamplerParams(); 2128 2129 logParams(samplerParams); 2130 renderTo(renderedFrame, samplerParams); 2131 verifyImage(renderedFrame, samplerParams); 2132 2133 return STOP; 2134 } 2135 2136 void TextureBorderClampPerAxisCase3D::logParams (const gls::TextureTestUtil::ReferenceParams& samplerParams) 2137 { 2138 const std::string borderColorString = (m_channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) ? (de::toString(m_borderColor.get<deInt32>())) 2139 : (m_channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) ? (de::toString(m_borderColor.get<deUint32>())) 2140 : (de::toString(m_borderColor.get<float>())); 2141 2142 m_testCtx.getLog() << tcu::TestLog::Message 2143 << "Border color is " << borderColorString << "\n" 2144 << "Texture lookup bias: " << samplerParams.colorBias << "\n" 2145 << "Texture lookup scale: " << samplerParams.colorScale << "\n" 2146 << "Filter: " << glu::getTextureFilterName(m_filter) << "\n" 2147 << "Wrap mode: s = " << glu::getRepeatModeStr(m_sWrap) 2148 << ", t = " << glu::getRepeatModeStr(m_tWrap) 2149 << ", r = " << glu::getRepeatModeStr(m_rWrap) << "\n" 2150 << tcu::TestLog::EndMessage; 2151 } 2152 2153 void TextureBorderClampPerAxisCase3D::renderTo (tcu::Surface& surface, 2154 const gls::TextureTestUtil::ReferenceParams& samplerParams) 2155 { 2156 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2157 const gls::TextureTestUtil::RandomViewport viewport (m_context.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, getCaseSeed()); 2158 2159 // Bind to unit 0. 2160 gl.activeTexture(GL_TEXTURE0); 2161 gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture()); 2162 2163 // Setup filtering and wrap modes. 2164 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(samplerParams.sampler.wrapS)); 2165 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(samplerParams.sampler.wrapT)); 2166 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, glu::getGLWrapMode(samplerParams.sampler.wrapR)); 2167 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(samplerParams.sampler.minFilter)); 2168 gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(samplerParams.sampler.magFilter)); 2169 2170 switch (m_channelClass) 2171 { 2172 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 2173 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 2174 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 2175 gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<float>()); 2176 break; 2177 2178 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 2179 gl.texParameterIiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deInt32>()); 2180 break; 2181 2182 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 2183 gl.texParameterIuiv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, m_borderColor.getAccess<deUint32>()); 2184 break; 2185 2186 default: 2187 DE_ASSERT(false); 2188 } 2189 2190 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state"); 2191 2192 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); 2193 m_renderer->renderQuad(0, &m_texCoords[0], samplerParams); 2194 glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, surface.getAccess()); 2195 } 2196 2197 void TextureBorderClampPerAxisCase3D::verifyImage (const tcu::Surface& renderedFrame, 2198 const gls::TextureTestUtil::ReferenceParams& samplerParams) 2199 { 2200 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat(); 2201 const int colorErrorBits = 2; 2202 const tcu::IVec4 colorBits = tcu::max(gls::TextureTestUtil::getBitsVec(pixelFormat) - tcu::IVec4(colorErrorBits), tcu::IVec4(0)); 2203 tcu::Surface reference (renderedFrame.getWidth(), renderedFrame.getHeight()); 2204 tcu::Surface errorMask (renderedFrame.getWidth(), renderedFrame.getHeight()); 2205 tcu::LodPrecision lodPrecision; 2206 tcu::LookupPrecision lookupPrecision; 2207 int numFailedPixels; 2208 2209 lodPrecision.derivateBits = 18; 2210 lodPrecision.lodBits = 5; 2211 2212 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(colorBits) / samplerParams.colorScale; 2213 lookupPrecision.coordBits = tcu::IVec3(20,20,0); 2214 lookupPrecision.uvwBits = tcu::IVec3(5,5,0); 2215 lookupPrecision.colorMask = gls::TextureTestUtil::getCompareMask(pixelFormat); 2216 2217 gls::TextureTestUtil::sampleTexture(gls::TextureTestUtil::SurfaceAccess(reference, pixelFormat), m_texture->getRefTexture(), &m_texCoords[0], samplerParams); 2218 2219 numFailedPixels = gls::TextureTestUtil::computeTextureLookupDiff(renderedFrame.getAccess(), reference.getAccess(), errorMask.getAccess(), m_texture->getRefTexture(), 2220 &m_texCoords[0], samplerParams, lookupPrecision, lodPrecision, m_testCtx.getWatchDog()); 2221 2222 if (numFailedPixels > 0) 2223 m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels << " invalid pixels!" << tcu::TestLog::EndMessage; 2224 m_testCtx.getLog() << tcu::TestLog::ImageSet("VerifyResult", "Verification result") 2225 << tcu::TestLog::Image("Rendered", "Rendered image", renderedFrame); 2226 if (numFailedPixels > 0) 2227 { 2228 m_testCtx.getLog() << tcu::TestLog::Image("Reference", "Ideal reference image", reference) 2229 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask); 2230 } 2231 m_testCtx.getLog() << tcu::TestLog::EndImageSet; 2232 2233 if (numFailedPixels == 0) 2234 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2235 else 2236 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 2237 } 2238 2239 gls::TextureTestUtil::ReferenceParams TextureBorderClampPerAxisCase3D::getSamplerParams (void) const 2240 { 2241 const tcu::TextureFormat texFormat = m_texture->getRefTexture().getFormat(); 2242 gls::TextureTestUtil::ReferenceParams refParams (gls::TextureTestUtil::TEXTURETYPE_3D); 2243 2244 refParams.sampler = glu::mapGLSampler(m_sWrap, m_tWrap, m_rWrap, m_filter, m_filter); 2245 refParams.sampler.borderColor = m_borderColor; 2246 refParams.lodMode = gls::TextureTestUtil::LODMODE_EXACT; 2247 refParams.samplerType = gls::TextureTestUtil::getSamplerType(texFormat); 2248 refParams.colorScale = m_lookupScale; 2249 refParams.colorBias = m_lookupBias; 2250 2251 return refParams; 2252 } 2253 2254 deUint32 TextureBorderClampPerAxisCase3D::getCaseSeed (void) const 2255 { 2256 tcu::SeedBuilder builder; 2257 builder << std::string(getName()) 2258 << m_texFormat 2259 << m_filter 2260 << m_sWrap 2261 << m_tWrap 2262 << m_rWrap 2263 << m_texture->getRefTexture().getWidth() 2264 << m_texture->getRefTexture().getHeight() 2265 << m_texture->getRefTexture().getDepth(); 2266 return builder.get(); 2267 } 2268 2269 } // anonymous 2270 2271 TextureBorderClampTests::TextureBorderClampTests (Context& context) 2272 : TestCaseGroup(context, "border_clamp", "EXT_texture_border_clamp tests") 2273 { 2274 } 2275 2276 TextureBorderClampTests::~TextureBorderClampTests (void) 2277 { 2278 } 2279 2280 void TextureBorderClampTests::init (void) 2281 { 2282 static const struct 2283 { 2284 const char* name; 2285 deUint32 filter; 2286 TextureBorderClampTest::SamplingFunction sampling; 2287 } s_filters[] = 2288 { 2289 { "nearest", GL_NEAREST, TextureBorderClampTest::SAMPLE_FILTER }, 2290 { "linear", GL_LINEAR, TextureBorderClampTest::SAMPLE_FILTER }, 2291 { "gather", GL_NEAREST, TextureBorderClampTest::SAMPLE_GATHER }, 2292 }; 2293 2294 // .formats 2295 { 2296 static const struct 2297 { 2298 const char* name; 2299 deUint32 format; 2300 tcu::Sampler::DepthStencilMode mode; 2301 } formats[] = 2302 { 2303 { "luminance", GL_LUMINANCE, tcu::Sampler::MODE_LAST }, 2304 { "alpha", GL_ALPHA, tcu::Sampler::MODE_LAST }, 2305 { "luminance_alpha", GL_LUMINANCE_ALPHA, tcu::Sampler::MODE_LAST }, 2306 { "bgra", GL_BGRA, tcu::Sampler::MODE_LAST }, 2307 { "r8", GL_R8, tcu::Sampler::MODE_LAST }, 2308 { "r8_snorm", GL_R8_SNORM, tcu::Sampler::MODE_LAST }, 2309 { "rg8", GL_RG8, tcu::Sampler::MODE_LAST }, 2310 { "rg8_snorm", GL_RG8_SNORM, tcu::Sampler::MODE_LAST }, 2311 { "rgb8", GL_RGB8, tcu::Sampler::MODE_LAST }, 2312 { "rgb8_snorm", GL_RGB8_SNORM, tcu::Sampler::MODE_LAST }, 2313 { "rgb565", GL_RGB565, tcu::Sampler::MODE_LAST }, 2314 { "rgba4", GL_RGBA4, tcu::Sampler::MODE_LAST }, 2315 { "rgb5_a1", GL_RGB5_A1, tcu::Sampler::MODE_LAST }, 2316 { "rgba8", GL_RGBA8, tcu::Sampler::MODE_LAST }, 2317 { "rgba8_snorm", GL_RGBA8_SNORM, tcu::Sampler::MODE_LAST }, 2318 { "rgb10_a2", GL_RGB10_A2, tcu::Sampler::MODE_LAST }, 2319 { "rgb10_a2ui", GL_RGB10_A2UI, tcu::Sampler::MODE_LAST }, 2320 { "srgb8", GL_SRGB8, tcu::Sampler::MODE_LAST }, 2321 { "srgb8_alpha8", GL_SRGB8_ALPHA8, tcu::Sampler::MODE_LAST }, 2322 { "r16f", GL_R16F, tcu::Sampler::MODE_LAST }, 2323 { "rg16f", GL_RG16F, tcu::Sampler::MODE_LAST }, 2324 { "rgb16f", GL_RGB16F, tcu::Sampler::MODE_LAST }, 2325 { "rgba16f", GL_RGBA16F, tcu::Sampler::MODE_LAST }, 2326 { "r32f", GL_R32F, tcu::Sampler::MODE_LAST }, 2327 { "rg32f", GL_RG32F, tcu::Sampler::MODE_LAST }, 2328 { "rgb32f", GL_RGB32F, tcu::Sampler::MODE_LAST }, 2329 { "rgba32f", GL_RGBA32F, tcu::Sampler::MODE_LAST }, 2330 { "r11f_g11f_b10f", GL_R11F_G11F_B10F, tcu::Sampler::MODE_LAST }, 2331 { "rgb9_e5", GL_RGB9_E5, tcu::Sampler::MODE_LAST }, 2332 { "r8i", GL_R8I, tcu::Sampler::MODE_LAST }, 2333 { "r8ui", GL_R8UI, tcu::Sampler::MODE_LAST }, 2334 { "r16i", GL_R16I, tcu::Sampler::MODE_LAST }, 2335 { "r16ui", GL_R16UI, tcu::Sampler::MODE_LAST }, 2336 { "r32i", GL_R32I, tcu::Sampler::MODE_LAST }, 2337 { "r32ui", GL_R32UI, tcu::Sampler::MODE_LAST }, 2338 { "rg8i", GL_RG8I, tcu::Sampler::MODE_LAST }, 2339 { "rg8ui", GL_RG8UI, tcu::Sampler::MODE_LAST }, 2340 { "rg16i", GL_RG16I, tcu::Sampler::MODE_LAST }, 2341 { "rg16ui", GL_RG16UI, tcu::Sampler::MODE_LAST }, 2342 { "rg32i", GL_RG32I, tcu::Sampler::MODE_LAST }, 2343 { "rg32ui", GL_RG32UI, tcu::Sampler::MODE_LAST }, 2344 { "rgb8i", GL_RGB8I, tcu::Sampler::MODE_LAST }, 2345 { "rgb8ui", GL_RGB8UI, tcu::Sampler::MODE_LAST }, 2346 { "rgb16i", GL_RGB16I, tcu::Sampler::MODE_LAST }, 2347 { "rgb16ui", GL_RGB16UI, tcu::Sampler::MODE_LAST }, 2348 { "rgb32i", GL_RGB32I, tcu::Sampler::MODE_LAST }, 2349 { "rgb32ui", GL_RGB32UI, tcu::Sampler::MODE_LAST }, 2350 { "rgba8i", GL_RGBA8I, tcu::Sampler::MODE_LAST }, 2351 { "rgba8ui", GL_RGBA8UI, tcu::Sampler::MODE_LAST }, 2352 { "rgba16i", GL_RGBA16I, tcu::Sampler::MODE_LAST }, 2353 { "rgba16ui", GL_RGBA16UI, tcu::Sampler::MODE_LAST }, 2354 { "rgba32i", GL_RGBA32I, tcu::Sampler::MODE_LAST }, 2355 { "rgba32ui", GL_RGBA32UI, tcu::Sampler::MODE_LAST }, 2356 { "depth_component16", GL_DEPTH_COMPONENT16, tcu::Sampler::MODE_DEPTH }, 2357 { "depth_component24", GL_DEPTH_COMPONENT24, tcu::Sampler::MODE_DEPTH }, 2358 { "depth_component32f", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH }, 2359 { "stencil_index8", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL }, 2360 { "depth24_stencil8_sample_depth", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_DEPTH }, 2361 { "depth32f_stencil8_sample_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH }, 2362 { "depth24_stencil8_sample_stencil", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_STENCIL }, 2363 { "depth32f_stencil8_sample_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL }, 2364 { "compressed_r11_eac", GL_COMPRESSED_R11_EAC, tcu::Sampler::MODE_LAST }, 2365 { "compressed_signed_r11_eac", GL_COMPRESSED_SIGNED_R11_EAC, tcu::Sampler::MODE_LAST }, 2366 { "compressed_rg11_eac", GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST }, 2367 { "compressed_signed_rg11_eac", GL_COMPRESSED_SIGNED_RG11_EAC, tcu::Sampler::MODE_LAST }, 2368 { "compressed_rgb8_etc2", GL_COMPRESSED_RGB8_ETC2, tcu::Sampler::MODE_LAST }, 2369 { "compressed_srgb8_etc2", GL_COMPRESSED_SRGB8_ETC2, tcu::Sampler::MODE_LAST }, 2370 { "compressed_rgb8_punchthrough_alpha1_etc2", GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, tcu::Sampler::MODE_LAST }, 2371 { "compressed_srgb8_punchthrough_alpha1_etc2", GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, tcu::Sampler::MODE_LAST }, 2372 { "compressed_rgba8_etc2_eac", GL_COMPRESSED_RGBA8_ETC2_EAC, tcu::Sampler::MODE_LAST }, 2373 { "compressed_srgb8_alpha8_etc2_eac", GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, tcu::Sampler::MODE_LAST }, 2374 }; 2375 2376 tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "Format tests"); 2377 addChild(formatsGroup); 2378 2379 // .format 2380 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx) 2381 { 2382 const deUint32 format = formats[formatNdx].format; 2383 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode; 2384 const bool isCompressed = glu::isCompressedFormat(format); 2385 const bool coreFilterable = isCoreFilterableFormat(format, sampleMode); 2386 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test"); 2387 2388 formatsGroup->addChild(formatGroup); 2389 2390 // .nearest 2391 // .linear 2392 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx) 2393 { 2394 // [not-compressed] 2395 // .size_pot 2396 // .size_npot 2397 // [compressed] 2398 // .size_tile_multiple (also pot) 2399 // .size_not_tile_multiple (also npot) 2400 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx) 2401 { 2402 const bool isNpotCase = (sizeNdx == 1); 2403 const char* const sizePotName = (!isCompressed) ? ("size_pot") : ("size_tile_multiple"); 2404 const char* const sizeNpotName = (!isCompressed) ? ("size_npot") : ("size_not_tile_multiple"); 2405 const char* const sizeName = (isNpotCase) ? (sizeNpotName) : (sizePotName); 2406 const SizeType sizeType = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT); 2407 const std::string caseName = std::string() + s_filters[filterNdx].name + "_" + sizeName; 2408 const deUint32 filter = s_filters[filterNdx].filter; 2409 2410 if (coreFilterable || !filterRequiresFilterability(filter)) 2411 formatGroup->addChild(new TextureBorderClampFormatCase(m_context, 2412 caseName.c_str(), 2413 "", 2414 format, 2415 sampleMode, 2416 TextureBorderClampFormatCase::STATE_TEXTURE_PARAM, 2417 sizeType, 2418 filter, 2419 s_filters[filterNdx].sampling)); 2420 } 2421 } 2422 } 2423 } 2424 2425 // .range_clamp 2426 { 2427 static const struct 2428 { 2429 const char* name; 2430 deUint32 format; 2431 tcu::Sampler::DepthStencilMode mode; 2432 } formats[] = 2433 { 2434 { "unorm_color", GL_R8, tcu::Sampler::MODE_LAST }, 2435 { "snorm_color", GL_R8_SNORM, tcu::Sampler::MODE_LAST }, 2436 { "float_color", GL_RG32F, tcu::Sampler::MODE_LAST }, 2437 { "int_color", GL_R8I, tcu::Sampler::MODE_LAST }, 2438 { "uint_color", GL_R16UI, tcu::Sampler::MODE_LAST }, 2439 { "srgb_color", GL_SRGB8_ALPHA8, tcu::Sampler::MODE_LAST }, 2440 { "unorm_depth", GL_DEPTH_COMPONENT24, tcu::Sampler::MODE_DEPTH }, 2441 { "float_depth", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH }, 2442 { "uint_stencil", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL }, 2443 { "float_depth_uint_stencil_sample_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH }, 2444 { "float_depth_uint_stencil_sample_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL }, 2445 { "unorm_depth_uint_stencil_sample_depth", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_DEPTH }, 2446 { "unorm_depth_uint_stencil_sample_stencil", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_STENCIL }, 2447 { "compressed_color", GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST }, 2448 }; 2449 2450 tcu::TestCaseGroup* const rangeClampGroup = new tcu::TestCaseGroup(m_testCtx, "range_clamp", "Range clamp tests"); 2451 addChild(rangeClampGroup); 2452 2453 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx) 2454 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx) 2455 { 2456 const deUint32 format = formats[formatNdx].format; 2457 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode; 2458 const std::string caseName = std::string() + s_filters[filterNdx].name + "_" + formats[formatNdx].name; 2459 const deUint32 filter = s_filters[filterNdx].filter; 2460 const bool coreFilterable = isCoreFilterableFormat(format, sampleMode); 2461 2462 if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER) 2463 continue; 2464 2465 if (coreFilterable || !filterRequiresFilterability(filter)) 2466 rangeClampGroup->addChild(new TextureBorderClampRangeClampCase(m_context, caseName.c_str(), "", format, sampleMode, filter)); 2467 } 2468 } 2469 2470 // .sampler 2471 { 2472 static const struct 2473 { 2474 const char* name; 2475 deUint32 format; 2476 tcu::Sampler::DepthStencilMode mode; 2477 } formats[] = 2478 { 2479 { "unorm_color", GL_R8, tcu::Sampler::MODE_LAST }, 2480 { "snorm_color", GL_R8_SNORM, tcu::Sampler::MODE_LAST }, 2481 { "float_color", GL_RG32F, tcu::Sampler::MODE_LAST }, 2482 { "int_color", GL_R8I, tcu::Sampler::MODE_LAST }, 2483 { "uint_color", GL_R16UI, tcu::Sampler::MODE_LAST }, 2484 { "unorm_depth", GL_DEPTH_COMPONENT24, tcu::Sampler::MODE_DEPTH }, 2485 { "float_depth", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH }, 2486 { "uint_stencil", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL }, 2487 { "compressed_color", GL_COMPRESSED_RG11_EAC, tcu::Sampler::MODE_LAST }, 2488 }; 2489 2490 tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler param tests"); 2491 addChild(samplerGroup); 2492 2493 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx) 2494 { 2495 const deUint32 format = formats[formatNdx].format; 2496 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode; 2497 const char* caseName = formats[formatNdx].name; 2498 2499 samplerGroup->addChild(new TextureBorderClampFormatCase(m_context, 2500 caseName, 2501 "", 2502 format, 2503 sampleMode, 2504 TextureBorderClampFormatCase::STATE_SAMPLER_PARAM, 2505 SIZE_POT, 2506 GL_NEAREST, 2507 TextureBorderClampFormatCase::SAMPLE_FILTER)); 2508 } 2509 } 2510 2511 // .per_axis_wrap_mode 2512 { 2513 static const struct 2514 { 2515 const char* name; 2516 bool is3D; 2517 } targets[] = 2518 { 2519 { "texture_2d", false }, 2520 { "texture_3d", true }, 2521 }; 2522 static const struct 2523 { 2524 const char* name; 2525 deUint32 format; 2526 tcu::Sampler::DepthStencilMode mode; 2527 bool supports3D; 2528 } formats[] = 2529 { 2530 { "unorm_color", GL_RG8, tcu::Sampler::MODE_LAST, true }, 2531 { "snorm_color", GL_RG8_SNORM, tcu::Sampler::MODE_LAST, true }, 2532 { "float_color", GL_R32F, tcu::Sampler::MODE_LAST, true }, 2533 { "int_color", GL_RG16I, tcu::Sampler::MODE_LAST, true }, 2534 { "uint_color", GL_R8UI, tcu::Sampler::MODE_LAST, true }, 2535 { "unorm_depth", GL_DEPTH_COMPONENT16, tcu::Sampler::MODE_DEPTH, false }, 2536 { "float_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH, false }, 2537 { "uint_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL, false }, 2538 { "compressed_color", GL_COMPRESSED_RGB8_ETC2, tcu::Sampler::MODE_LAST, false }, 2539 }; 2540 static const struct 2541 { 2542 const char* name; 2543 deUint32 sWrap; 2544 deUint32 tWrap; 2545 deUint32 rWrap; 2546 bool is3D; 2547 } wrapConfigs[] = 2548 { 2549 // 2d configs 2550 { "s_clamp_to_edge_t_clamp_to_border", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_NONE, false }, 2551 { "s_repeat_t_clamp_to_border", GL_REPEAT, GL_CLAMP_TO_BORDER, GL_NONE, false }, 2552 { "s_mirrored_repeat_t_clamp_to_border", GL_MIRRORED_REPEAT, GL_CLAMP_TO_BORDER, GL_NONE, false }, 2553 2554 // 3d configs 2555 { "s_clamp_to_border_t_clamp_to_border_r_clamp_to_border", GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, true }, 2556 { "s_clamp_to_border_t_clamp_to_border_r_repeat", GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER, GL_REPEAT, true }, 2557 { "s_mirrored_repeat_t_clamp_to_border_r_repeat", GL_MIRRORED_REPEAT, GL_CLAMP_TO_BORDER, GL_REPEAT, true }, 2558 { "s_repeat_t_mirrored_repeat_r_clamp_to_border", GL_REPEAT, GL_MIRRORED_REPEAT, GL_CLAMP_TO_BORDER, true }, 2559 }; 2560 2561 tcu::TestCaseGroup* const perAxisGroup = new tcu::TestCaseGroup(m_testCtx, "per_axis_wrap_mode", "Per-axis wrapping modes"); 2562 addChild(perAxisGroup); 2563 2564 // .texture_nd 2565 for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(targets); ++targetNdx) 2566 { 2567 tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, targets[targetNdx].name, "Texture target test"); 2568 perAxisGroup->addChild(targetGroup); 2569 2570 // .format 2571 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx) 2572 { 2573 if (targets[targetNdx].is3D && !formats[formatNdx].supports3D) 2574 continue; 2575 else 2576 { 2577 const deUint32 format = formats[formatNdx].format; 2578 const tcu::Sampler::DepthStencilMode sampleMode = formats[formatNdx].mode; 2579 const bool coreFilterable = isCoreFilterableFormat(format, sampleMode); 2580 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test"); 2581 targetGroup->addChild(formatGroup); 2582 2583 // .linear 2584 // .nearest 2585 // .gather 2586 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx) 2587 { 2588 const deUint32 filter = s_filters[filterNdx].filter; 2589 2590 if (!coreFilterable && filterRequiresFilterability(filter)) 2591 { 2592 // skip linear on pure integers 2593 continue; 2594 } 2595 else if (s_filters[filterNdx].sampling == TextureBorderClampTest::SAMPLE_GATHER && targets[targetNdx].is3D) 2596 { 2597 // skip gather on 3d 2598 continue; 2599 } 2600 else 2601 { 2602 tcu::TestCaseGroup* const filteringGroup = new tcu::TestCaseGroup(m_testCtx, s_filters[filterNdx].name, "Tests with specific filter"); 2603 formatGroup->addChild(filteringGroup); 2604 2605 // .s_XXX_t_XXX(_r_XXX) 2606 for (int wrapNdx = 0; wrapNdx < DE_LENGTH_OF_ARRAY(wrapConfigs); ++wrapNdx) 2607 { 2608 if (wrapConfigs[wrapNdx].is3D != targets[targetNdx].is3D) 2609 continue; 2610 else 2611 { 2612 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx) 2613 { 2614 const char* const wrapName = wrapConfigs[wrapNdx].name; 2615 const bool isNpotCase = (sizeNdx == 1); 2616 const char* const sizeNameExtension = (isNpotCase) ? ("_npot") : ("_pot"); 2617 const SizeType size = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT); 2618 2619 if (!targets[targetNdx].is3D) 2620 filteringGroup->addChild(new TextureBorderClampPerAxisCase2D(m_context, 2621 (std::string() + wrapName + sizeNameExtension).c_str(), 2622 "", 2623 format, 2624 sampleMode, 2625 size, 2626 filter, 2627 wrapConfigs[wrapNdx].sWrap, 2628 wrapConfigs[wrapNdx].tWrap, 2629 s_filters[filterNdx].sampling)); 2630 else 2631 { 2632 DE_ASSERT(sampleMode == tcu::Sampler::MODE_LAST); 2633 filteringGroup->addChild(new TextureBorderClampPerAxisCase3D(m_context, 2634 (std::string() + wrapName + sizeNameExtension).c_str(), 2635 "", 2636 format, 2637 size, 2638 filter, 2639 wrapConfigs[wrapNdx].sWrap, 2640 wrapConfigs[wrapNdx].tWrap, 2641 wrapConfigs[wrapNdx].rWrap)); 2642 } 2643 } 2644 } 2645 } 2646 } 2647 } 2648 } 2649 } 2650 } 2651 } 2652 2653 // .depth_compare_mode 2654 { 2655 static const struct 2656 { 2657 const char* name; 2658 deUint32 format; 2659 } formats[] = 2660 { 2661 { "depth_component16", GL_DEPTH_COMPONENT16 }, 2662 { "depth_component24", GL_DEPTH_COMPONENT24 }, 2663 { "depth24_stencil8", GL_DEPTH24_STENCIL8 }, 2664 { "depth32f_stencil8", GL_DEPTH32F_STENCIL8 }, 2665 }; 2666 2667 tcu::TestCaseGroup* const compareGroup = new tcu::TestCaseGroup(m_testCtx, "depth_compare_mode", "Tests depth compare mode"); 2668 addChild(compareGroup); 2669 2670 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx) 2671 { 2672 const deUint32 format = formats[formatNdx].format; 2673 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, formats[formatNdx].name, "Format test"); 2674 2675 compareGroup->addChild(formatGroup); 2676 2677 // (format).(linear|nearest|gather)_(pot|npot) 2678 for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(s_filters); ++filterNdx) 2679 for (int sizeNdx = 0; sizeNdx < 2; ++sizeNdx) 2680 { 2681 const bool isNpotCase = (sizeNdx == 1); 2682 const char* const sizeName = (isNpotCase) ? ("size_npot") : ("size_pot"); 2683 const SizeType sizeType = (isNpotCase) ? (SIZE_NPOT) : (SIZE_POT); 2684 const std::string caseName = std::string() + s_filters[filterNdx].name + "_" + sizeName; 2685 const deUint32 filter = s_filters[filterNdx].filter; 2686 2687 formatGroup->addChild(new TextureBorderClampDepthCompareCase(m_context, 2688 caseName.c_str(), 2689 "", 2690 format, 2691 sizeType, 2692 filter, 2693 s_filters[filterNdx].sampling)); 2694 } 2695 } 2696 } 2697 2698 // unused channels (A in rgb, G in stencil etc.) 2699 { 2700 static const struct 2701 { 2702 const char* name; 2703 deUint32 format; 2704 tcu::Sampler::DepthStencilMode mode; 2705 } formats[] = 2706 { 2707 { "r8", GL_R8, tcu::Sampler::MODE_LAST }, 2708 { "rg8_snorm", GL_RG8_SNORM, tcu::Sampler::MODE_LAST }, 2709 { "rgb8", GL_RGB8, tcu::Sampler::MODE_LAST }, 2710 { "rg32f", GL_RG32F, tcu::Sampler::MODE_LAST }, 2711 { "r16i", GL_RG16I, tcu::Sampler::MODE_LAST }, 2712 { "luminance", GL_LUMINANCE, tcu::Sampler::MODE_LAST }, 2713 { "alpha", GL_ALPHA, tcu::Sampler::MODE_LAST }, 2714 { "luminance_alpha", GL_LUMINANCE_ALPHA, tcu::Sampler::MODE_LAST }, 2715 { "depth_component16", GL_DEPTH_COMPONENT16, tcu::Sampler::MODE_DEPTH }, 2716 { "depth_component32f", GL_DEPTH_COMPONENT32F, tcu::Sampler::MODE_DEPTH }, 2717 { "stencil_index8", GL_STENCIL_INDEX8, tcu::Sampler::MODE_STENCIL }, 2718 { "depth32f_stencil8_sample_depth", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_DEPTH }, 2719 { "depth32f_stencil8_sample_stencil", GL_DEPTH32F_STENCIL8, tcu::Sampler::MODE_STENCIL }, 2720 { "depth24_stencil8_sample_depth", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_DEPTH }, 2721 { "depth24_stencil8_sample_stencil", GL_DEPTH24_STENCIL8, tcu::Sampler::MODE_STENCIL }, 2722 { "compressed_r11_eac", GL_COMPRESSED_R11_EAC, tcu::Sampler::MODE_LAST }, 2723 }; 2724 2725 tcu::TestCaseGroup* const unusedGroup = new tcu::TestCaseGroup(m_testCtx, "unused_channels", "Tests channels that are not present in the internal format"); 2726 addChild(unusedGroup); 2727 2728 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx) 2729 { 2730 unusedGroup->addChild(new TextureBorderClampUnusedChannelCase(m_context, 2731 formats[formatNdx].name, 2732 "", 2733 formats[formatNdx].format, 2734 formats[formatNdx].mode)); 2735 } 2736 } 2737 } 2738 2739 } // Functional 2740 } // gles31 2741 } // deqp 2742