1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.0 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 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 ASTC decompression tests 22 * 23 * \todo Parts of the block-generation code are same as in decompression 24 * code in tcuCompressedTexture.cpp ; could put them to some shared 25 * ASTC utility file. 26 * 27 * \todo Tests for void extents with nontrivial extent coordinates. 28 * 29 * \todo Better checking of the error color. Currently legitimate error 30 * pixels are just ignored in image comparison; however, spec says 31 * that error color is either magenta or all-NaNs. Can NaNs cause 32 * troubles, or can we assume that NaNs are well-supported in shader 33 * if the implementation chooses NaNs as error color? 34 *//*--------------------------------------------------------------------*/ 35 36 #include "es3fASTCDecompressionCases.hpp" 37 #include "gluTexture.hpp" 38 #include "gluPixelTransfer.hpp" 39 #include "gluStrUtil.hpp" 40 #include "gluTextureUtil.hpp" 41 #include "glsTextureTestUtil.hpp" 42 #include "tcuCompressedTexture.hpp" 43 #include "tcuTestLog.hpp" 44 #include "tcuTextureUtil.hpp" 45 #include "tcuSurface.hpp" 46 #include "tcuVectorUtil.hpp" 47 #include "tcuImageCompare.hpp" 48 #include "deStringUtil.hpp" 49 #include "deRandom.hpp" 50 #include "deFloat16.h" 51 #include "deString.h" 52 #include "deMemory.h" 53 54 #include "glwFunctions.hpp" 55 #include "glwEnums.hpp" 56 57 #include <vector> 58 #include <string> 59 #include <algorithm> 60 61 using tcu::TestLog; 62 using tcu::CompressedTexture; 63 using tcu::CompressedTexFormat; 64 using tcu::IVec2; 65 using tcu::IVec3; 66 using tcu::IVec4; 67 using tcu::Vec2; 68 using tcu::Vec4; 69 using tcu::Sampler; 70 using tcu::Surface; 71 using tcu::astc::BlockTestType; 72 using std::vector; 73 using std::string; 74 75 namespace deqp 76 { 77 78 using gls::TextureTestUtil::TextureRenderer; 79 using gls::TextureTestUtil::RandomViewport; 80 using gls::TextureTestUtil::ReferenceParams; 81 82 namespace gles3 83 { 84 namespace Functional 85 { 86 87 namespace ASTCDecompressionCaseInternal 88 { 89 90 // Get a string describing the data of an ASTC block. Currently contains just hex and bin dumps of the block. 91 static string astcBlockDataStr (const deUint8* data) 92 { 93 string result; 94 result += " Hexadecimal (big endian: upper left hex digit is block bits 127 to 124):"; 95 96 { 97 static const char* const hexDigits = "0123456789ABCDEF"; 98 99 for (int i = tcu::astc::BLOCK_SIZE_BYTES-1; i >= 0; i--) 100 { 101 if ((i+1) % 2 == 0) 102 result += "\n "; 103 else 104 result += " "; 105 106 result += hexDigits[(data[i] & 0xf0) >> 4]; 107 result += " "; 108 result += hexDigits[(data[i] & 0x0f) >> 0]; 109 } 110 } 111 112 result += "\n\n Binary (big endian: upper left bit is block bit 127):"; 113 114 for (int i = tcu::astc::BLOCK_SIZE_BYTES-1; i >= 0; i--) 115 { 116 if ((i+1) % 2 == 0) 117 result += "\n "; 118 else 119 result += " "; 120 121 for (int j = 8-1; j >= 0; j--) 122 { 123 if (j == 3) 124 result += " "; 125 126 result += (data[i] >> j) & 1 ? "1" : "0"; 127 } 128 } 129 130 result += "\n"; 131 132 return result; 133 } 134 135 // Compare reference and result block images, reporting also the position of the first non-matching block. 136 static bool compareBlockImages (const Surface& reference, 137 const Surface& result, 138 const tcu::RGBA& thresholdRGBA, 139 const IVec2& blockSize, 140 int numNonDummyBlocks, 141 IVec2& firstFailedBlockCoordDst, 142 Surface& errorMaskDst, 143 IVec4& maxDiffDst) 144 { 145 TCU_CHECK_INTERNAL(reference.getWidth() == result.getWidth() && reference.getHeight() == result.getHeight()); 146 147 const int width = result.getWidth(); 148 const int height = result.getHeight(); 149 const IVec4 threshold = thresholdRGBA.toIVec(); 150 const int numXBlocks = width / blockSize.x(); 151 152 DE_ASSERT(width % blockSize.x() == 0 && height % blockSize.y() == 0); 153 154 errorMaskDst.setSize(width, height); 155 156 firstFailedBlockCoordDst = IVec2(-1, -1); 157 maxDiffDst = IVec4(0); 158 159 for (int y = 0; y < height; y++) 160 for (int x = 0; x < width; x++) 161 { 162 const IVec2 blockCoord = IVec2(x, y) / blockSize; 163 164 if (blockCoord.y()*numXBlocks + blockCoord.x() < numNonDummyBlocks) 165 { 166 const IVec4 refPix = reference.getPixel(x, y).toIVec(); 167 168 if (refPix == IVec4(255, 0, 255, 255)) 169 { 170 // ASTC error color - allow anything in result. 171 errorMaskDst.setPixel(x, y, tcu::RGBA(255, 0, 255, 255)); 172 continue; 173 } 174 175 const IVec4 resPix = result.getPixel(x, y).toIVec(); 176 const IVec4 diff = tcu::abs(refPix - resPix); 177 const bool isOk = tcu::boolAll(tcu::lessThanEqual(diff, threshold)); 178 179 maxDiffDst = tcu::max(maxDiffDst, diff); 180 181 errorMaskDst.setPixel(x, y, isOk ? tcu::RGBA::green() : tcu::RGBA::red()); 182 183 if (!isOk && firstFailedBlockCoordDst.x() == -1) 184 firstFailedBlockCoordDst = blockCoord; 185 } 186 } 187 188 return boolAll(lessThanEqual(maxDiffDst, threshold)); 189 } 190 191 enum ASTCSupportLevel 192 { 193 // \note Ordered from smallest subset to full, for convenient comparison. 194 ASTCSUPPORTLEVEL_NONE = 0, 195 ASTCSUPPORTLEVEL_LDR, 196 ASTCSUPPORTLEVEL_HDR, 197 ASTCSUPPORTLEVEL_FULL 198 }; 199 200 static inline ASTCSupportLevel getASTCSupportLevel (const glu::ContextInfo& contextInfo, const glu::RenderContext& renderCtx) 201 { 202 const bool isES32 = glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3, 2)); 203 204 const vector<string>& extensions = contextInfo.getExtensions(); 205 206 ASTCSupportLevel maxLevel = ASTCSUPPORTLEVEL_NONE; 207 208 for (int extNdx = 0; extNdx < (int)extensions.size(); extNdx++) 209 { 210 const string& ext = extensions[extNdx]; 211 if (isES32) 212 { 213 maxLevel = de::max(maxLevel, ext == "GL_KHR_texture_compression_astc_hdr" ? ASTCSUPPORTLEVEL_HDR 214 : ext == "GL_OES_texture_compression_astc" ? ASTCSUPPORTLEVEL_FULL 215 : ASTCSUPPORTLEVEL_LDR); 216 } 217 else 218 { 219 maxLevel = de::max(maxLevel, ext == "GL_KHR_texture_compression_astc_ldr" ? ASTCSUPPORTLEVEL_LDR 220 : ext == "GL_KHR_texture_compression_astc_hdr" ? ASTCSUPPORTLEVEL_HDR 221 : ext == "GL_OES_texture_compression_astc" ? ASTCSUPPORTLEVEL_FULL 222 : ASTCSUPPORTLEVEL_NONE); 223 } 224 } 225 226 return maxLevel; 227 } 228 229 // Class handling the common rendering stuff of ASTC cases. 230 class ASTCRenderer2D 231 { 232 public: 233 ASTCRenderer2D (Context& context, 234 CompressedTexFormat format, 235 deUint32 randomSeed); 236 237 ~ASTCRenderer2D (void); 238 239 void initialize (int minRenderWidth, int minRenderHeight, const Vec4& colorScale, const Vec4& colorBias); 240 void clear (void); 241 242 void render (Surface& referenceDst, 243 Surface& resultDst, 244 const glu::Texture2D& texture, 245 const tcu::TextureFormat& uncompressedFormat); 246 247 CompressedTexFormat getFormat (void) const { return m_format; } 248 IVec2 getBlockSize (void) const { return m_blockSize; } 249 ASTCSupportLevel getASTCSupport (void) const { DE_ASSERT(m_initialized); return m_astcSupport; } 250 251 private: 252 Context& m_context; 253 TextureRenderer m_renderer; 254 255 const CompressedTexFormat m_format; 256 const IVec2 m_blockSize; 257 ASTCSupportLevel m_astcSupport; 258 Vec4 m_colorScale; 259 Vec4 m_colorBias; 260 261 de::Random m_rnd; 262 263 bool m_initialized; 264 }; 265 266 } // ASTCDecompressionCaseInternal 267 268 using namespace ASTCDecompressionCaseInternal; 269 270 ASTCRenderer2D::ASTCRenderer2D (Context& context, 271 CompressedTexFormat format, 272 deUint32 randomSeed) 273 : m_context (context) 274 , m_renderer (context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP) 275 , m_format (format) 276 , m_blockSize (tcu::getBlockPixelSize(format).xy()) 277 , m_astcSupport (ASTCSUPPORTLEVEL_NONE) 278 , m_colorScale (-1.0f) 279 , m_colorBias (-1.0f) 280 , m_rnd (randomSeed) 281 , m_initialized (false) 282 { 283 DE_ASSERT(tcu::getBlockPixelSize(format).z() == 1); 284 } 285 286 ASTCRenderer2D::~ASTCRenderer2D (void) 287 { 288 clear(); 289 } 290 291 void ASTCRenderer2D::initialize (int minRenderWidth, int minRenderHeight, const Vec4& colorScale, const Vec4& colorBias) 292 { 293 DE_ASSERT(!m_initialized); 294 295 const tcu::RenderTarget& renderTarget = m_context.getRenderTarget(); 296 TestLog& log = m_context.getTestContext().getLog(); 297 298 m_astcSupport = getASTCSupportLevel(m_context.getContextInfo(), m_context.getRenderContext()); 299 m_colorScale = colorScale; 300 m_colorBias = colorBias; 301 302 switch (m_astcSupport) 303 { 304 case ASTCSUPPORTLEVEL_NONE: log << TestLog::Message << "No ASTC support detected" << TestLog::EndMessage; throw tcu::NotSupportedError("ASTC not supported"); 305 case ASTCSUPPORTLEVEL_LDR: log << TestLog::Message << "LDR ASTC support detected" << TestLog::EndMessage; break; 306 case ASTCSUPPORTLEVEL_HDR: log << TestLog::Message << "HDR ASTC support detected" << TestLog::EndMessage; break; 307 case ASTCSUPPORTLEVEL_FULL: log << TestLog::Message << "Full ASTC support detected" << TestLog::EndMessage; break; 308 default: 309 DE_ASSERT(false); 310 } 311 312 if (renderTarget.getWidth() < minRenderWidth || renderTarget.getHeight() < minRenderHeight) 313 throw tcu::NotSupportedError("Render target must be at least " + de::toString(minRenderWidth) + "x" + de::toString(minRenderHeight)); 314 315 log << TestLog::Message << "Using color scale and bias: result = raw * " << colorScale << " + " << colorBias << TestLog::EndMessage; 316 317 m_initialized = true; 318 } 319 320 void ASTCRenderer2D::clear (void) 321 { 322 m_renderer.clear(); 323 } 324 325 void ASTCRenderer2D::render (Surface& referenceDst, Surface& resultDst, const glu::Texture2D& texture, const tcu::TextureFormat& uncompressedFormat) 326 { 327 DE_ASSERT(m_initialized); 328 329 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 330 const glu::RenderContext& renderCtx = m_context.getRenderContext(); 331 const int textureWidth = texture.getRefTexture().getWidth(); 332 const int textureHeight = texture.getRefTexture().getHeight(); 333 const RandomViewport viewport (renderCtx.getRenderTarget(), textureWidth, textureHeight, m_rnd.getUint32()); 334 ReferenceParams renderParams (gls::TextureTestUtil::TEXTURETYPE_2D); 335 vector<float> texCoord; 336 gls::TextureTestUtil::computeQuadTexCoord2D(texCoord, Vec2(0.0f, 0.0f), Vec2(1.0f, 1.0f)); 337 338 renderParams.samplerType = gls::TextureTestUtil::getSamplerType(uncompressedFormat); 339 renderParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST); 340 renderParams.colorScale = m_colorScale; 341 renderParams.colorBias = m_colorBias; 342 343 // Setup base viewport. 344 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); 345 346 // Bind to unit 0. 347 gl.activeTexture(GL_TEXTURE0); 348 gl.bindTexture(GL_TEXTURE_2D, texture.getGLTexture()); 349 350 // Setup nearest neighbor filtering and clamp-to-edge. 351 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 352 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 353 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 354 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 355 356 GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state"); 357 358 // Issue GL draws. 359 m_renderer.renderQuad(0, &texCoord[0], renderParams); 360 gl.flush(); 361 362 // Compute reference. 363 sampleTexture(gls::TextureTestUtil::SurfaceAccess(referenceDst, renderCtx.getRenderTarget().getPixelFormat()), texture.getRefTexture(), &texCoord[0], renderParams); 364 365 // Read GL-rendered image. 366 glu::readPixels(renderCtx, viewport.x, viewport.y, resultDst.getAccess()); 367 } 368 369 ASTCBlockCase2D::ASTCBlockCase2D (Context& context, 370 const char* name, 371 const char* description, 372 BlockTestType testType, 373 CompressedTexFormat format) 374 : TestCase (context, name, description) 375 , m_testType (testType) 376 , m_format (format) 377 , m_numBlocksTested (0) 378 , m_currentIteration (0) 379 , m_renderer (new ASTCRenderer2D(context, format, deStringHash(getName()))) 380 { 381 DE_ASSERT(!(tcu::isAstcSRGBFormat(m_format) && tcu::astc::isBlockTestTypeHDROnly(m_testType))); // \note There is no HDR sRGB mode, so these would be redundant. 382 } 383 384 ASTCBlockCase2D::~ASTCBlockCase2D (void) 385 { 386 ASTCBlockCase2D::deinit(); 387 } 388 389 void ASTCBlockCase2D::init (void) 390 { 391 m_renderer->initialize(64, 64, tcu::astc::getBlockTestTypeColorScale(m_testType), tcu::astc::getBlockTestTypeColorBias(m_testType)); 392 393 generateBlockCaseTestData(m_blockData, m_format, m_testType); 394 DE_ASSERT(!m_blockData.empty()); 395 DE_ASSERT(m_blockData.size() % tcu::astc::BLOCK_SIZE_BYTES == 0); 396 397 m_testCtx.getLog() << TestLog::Message << "Total " << m_blockData.size() / tcu::astc::BLOCK_SIZE_BYTES << " blocks to test" << TestLog::EndMessage 398 << TestLog::Message << "Note: Legitimate ASTC error pixels will be ignored when comparing to reference" << TestLog::EndMessage; 399 } 400 401 void ASTCBlockCase2D::deinit (void) 402 { 403 m_renderer->clear(); 404 m_blockData.clear(); 405 } 406 407 ASTCBlockCase2D::IterateResult ASTCBlockCase2D::iterate (void) 408 { 409 TestLog& log = m_testCtx.getLog(); 410 411 if (m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR && tcu::astc::isBlockTestTypeHDROnly(m_testType)) 412 { 413 log << TestLog::Message << "Passing the case immediately, since only LDR support was detected and test only contains HDR blocks" << TestLog::EndMessage; 414 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 415 return STOP; 416 } 417 418 const IVec2 blockSize = m_renderer->getBlockSize(); 419 const int totalNumBlocks = (int)m_blockData.size() / tcu::astc::BLOCK_SIZE_BYTES; 420 const int numXBlocksPerImage = de::min(m_context.getRenderTarget().getWidth(), 512) / blockSize.x(); 421 const int numYBlocksPerImage = de::min(m_context.getRenderTarget().getHeight(), 512) / blockSize.y(); 422 const int numBlocksPerImage = numXBlocksPerImage * numYBlocksPerImage; 423 const int imageWidth = numXBlocksPerImage * blockSize.x(); 424 const int imageHeight = numYBlocksPerImage * blockSize.y(); 425 const int numBlocksRemaining = totalNumBlocks - m_numBlocksTested; 426 const int curNumNonDummyBlocks = de::min(numBlocksPerImage, numBlocksRemaining); 427 const int curNumDummyBlocks = numBlocksPerImage - curNumNonDummyBlocks; 428 const glu::RenderContext& renderCtx = m_context.getRenderContext(); 429 const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + (tcu::isAstcSRGBFormat(m_format) ? tcu::RGBA(2,2,2,2) : tcu::RGBA(1,1,1,1)); 430 tcu::CompressedTexture compressed (m_format, imageWidth, imageHeight); 431 432 if (m_currentIteration == 0) 433 { 434 log << TestLog::Message << "Using texture of size " 435 << imageWidth << "x" << imageHeight 436 << ", with " << numXBlocksPerImage << " block columns and " << numYBlocksPerImage << " block rows " 437 << ", with block size " << blockSize.x() << "x" << blockSize.y() 438 << TestLog::EndMessage; 439 } 440 441 DE_ASSERT(compressed.getDataSize() == numBlocksPerImage*tcu::astc::BLOCK_SIZE_BYTES); 442 deMemcpy(compressed.getData(), &m_blockData[m_numBlocksTested*tcu::astc::BLOCK_SIZE_BYTES], curNumNonDummyBlocks*tcu::astc::BLOCK_SIZE_BYTES); 443 if (curNumDummyBlocks > 1) 444 tcu::astc::generateDummyVoidExtentBlocks((deUint8*)compressed.getData() + curNumNonDummyBlocks*tcu::astc::BLOCK_SIZE_BYTES, curNumDummyBlocks); 445 446 // Create texture and render. 447 448 glu::Texture2D texture (renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams((m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR ? tcu::TexDecompressionParams::ASTCMODE_LDR : tcu::TexDecompressionParams::ASTCMODE_HDR))); 449 Surface renderedFrame (imageWidth, imageHeight); 450 Surface referenceFrame (imageWidth, imageHeight); 451 452 m_renderer->render(referenceFrame, renderedFrame, texture, getUncompressedFormat(compressed.getFormat())); 453 454 // Compare and log. 455 // \note Since a case can draw quite many images, only log the first iteration and failures. 456 457 { 458 Surface errorMask; 459 IVec2 firstFailedBlockCoord; 460 IVec4 maxDiff; 461 const bool compareOk = compareBlockImages(referenceFrame, renderedFrame, threshold, blockSize, curNumNonDummyBlocks, firstFailedBlockCoord, errorMask, maxDiff); 462 463 if (m_currentIteration == 0 || !compareOk) 464 { 465 const char* const imageSetName = "ComparisonResult"; 466 const char* const imageSetDesc = "Comparison Result"; 467 468 { 469 tcu::ScopedLogSection section(log, "Iteration " + de::toString(m_currentIteration), 470 "Blocks " + de::toString(m_numBlocksTested) + " to " + de::toString(m_numBlocksTested + curNumNonDummyBlocks - 1)); 471 472 if (curNumDummyBlocks > 0) 473 log << TestLog::Message << "Note: Only the first " << curNumNonDummyBlocks << " blocks in the image are relevant; rest " << curNumDummyBlocks << " are dummies and not checked" << TestLog::EndMessage; 474 475 if (!compareOk) 476 { 477 log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage 478 << TestLog::ImageSet(imageSetName, imageSetDesc) 479 << TestLog::Image("Result", "Result", renderedFrame) 480 << TestLog::Image("Reference", "Reference", referenceFrame) 481 << TestLog::Image("ErrorMask", "Error mask", errorMask) 482 << TestLog::EndImageSet; 483 484 const int blockNdx = m_numBlocksTested + firstFailedBlockCoord.y()*numXBlocksPerImage + firstFailedBlockCoord.x(); 485 DE_ASSERT(blockNdx < totalNumBlocks); 486 487 log << TestLog::Message << "First failed block at column " << firstFailedBlockCoord.x() << " and row " << firstFailedBlockCoord.y() << TestLog::EndMessage 488 << TestLog::Message << "Data of first failed block:\n" << astcBlockDataStr(&m_blockData[blockNdx*tcu::astc::BLOCK_SIZE_BYTES]) << TestLog::EndMessage; 489 490 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 491 return STOP; 492 } 493 else 494 { 495 log << TestLog::ImageSet(imageSetName, imageSetDesc) 496 << TestLog::Image("Result", "Result", renderedFrame) 497 << TestLog::EndImageSet; 498 } 499 } 500 501 if (m_numBlocksTested + curNumNonDummyBlocks < totalNumBlocks) 502 log << TestLog::Message << "Note: not logging further images unless reference comparison fails" << TestLog::EndMessage; 503 } 504 } 505 506 m_currentIteration++; 507 m_numBlocksTested += curNumNonDummyBlocks; 508 509 if (m_numBlocksTested >= totalNumBlocks) 510 { 511 DE_ASSERT(m_numBlocksTested == totalNumBlocks); 512 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 513 return STOP; 514 } 515 516 return CONTINUE; 517 } 518 519 520 521 ASTCBlockSizeRemainderCase2D::ASTCBlockSizeRemainderCase2D (Context& context, 522 const char* name, 523 const char* description, 524 CompressedTexFormat format) 525 : TestCase (context, name, description) 526 , m_format (format) 527 , m_currentIteration (0) 528 , m_renderer (new ASTCRenderer2D(context, format, deStringHash(getName()))) 529 { 530 } 531 532 ASTCBlockSizeRemainderCase2D::~ASTCBlockSizeRemainderCase2D (void) 533 { 534 ASTCBlockSizeRemainderCase2D::deinit(); 535 } 536 537 void ASTCBlockSizeRemainderCase2D::init (void) 538 { 539 const IVec2 blockSize = m_renderer->getBlockSize(); 540 m_renderer->initialize(MAX_NUM_BLOCKS_X*blockSize.x(), MAX_NUM_BLOCKS_Y*blockSize.y(), Vec4(1.0f), Vec4(0.0f)); 541 } 542 543 void ASTCBlockSizeRemainderCase2D::deinit (void) 544 { 545 m_renderer->clear(); 546 } 547 548 ASTCBlockSizeRemainderCase2D::IterateResult ASTCBlockSizeRemainderCase2D::iterate (void) 549 { 550 TestLog& log = m_testCtx.getLog(); 551 const IVec2 blockSize = m_renderer->getBlockSize(); 552 const int curRemainderX = m_currentIteration % blockSize.x(); 553 const int curRemainderY = m_currentIteration / blockSize.x(); 554 const int imageWidth = (MAX_NUM_BLOCKS_X-1)*blockSize.x() + curRemainderX; 555 const int imageHeight = (MAX_NUM_BLOCKS_Y-1)*blockSize.y() + curRemainderY; 556 const int numBlocksX = deDivRoundUp32(imageWidth, blockSize.x()); 557 const int numBlocksY = deDivRoundUp32(imageHeight, blockSize.y()); 558 const int totalNumBlocks = numBlocksX * numBlocksY; 559 const glu::RenderContext& renderCtx = m_context.getRenderContext(); 560 const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + (tcu::isAstcSRGBFormat(m_format) ? tcu::RGBA(2,2,2,2) : tcu::RGBA(1,1,1,1)); 561 tcu::CompressedTexture compressed (m_format, imageWidth, imageHeight); 562 563 DE_ASSERT(compressed.getDataSize() == totalNumBlocks*tcu::astc::BLOCK_SIZE_BYTES); 564 tcu::astc::generateDummyNormalBlocks((deUint8*)compressed.getData(), totalNumBlocks, blockSize.x(), blockSize.y()); 565 566 // Create texture and render. 567 568 Surface renderedFrame (imageWidth, imageHeight); 569 Surface referenceFrame (imageWidth, imageHeight); 570 glu::Texture2D texture (renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams(m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR ? tcu::TexDecompressionParams::ASTCMODE_LDR : tcu::TexDecompressionParams::ASTCMODE_HDR)); 571 572 m_renderer->render(referenceFrame, renderedFrame, texture, getUncompressedFormat(compressed.getFormat())); 573 574 { 575 // Compare and log. 576 577 tcu::ScopedLogSection section(log, "Iteration " + de::toString(m_currentIteration), 578 "Remainder " + de::toString(curRemainderX) + "x" + de::toString(curRemainderY)); 579 580 log << TestLog::Message << "Using texture of size " 581 << imageWidth << "x" << imageHeight 582 << " and block size " 583 << blockSize.x() << "x" << blockSize.y() 584 << "; the x and y remainders are " 585 << curRemainderX << " and " << curRemainderY << " respectively" 586 << TestLog::EndMessage; 587 588 const bool compareOk = tcu::pixelThresholdCompare(m_testCtx.getLog(), "ComparisonResult", "Comparison Result", referenceFrame, renderedFrame, threshold, 589 m_currentIteration == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR); 590 591 if (!compareOk) 592 { 593 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 594 return STOP; 595 } 596 } 597 598 if (m_currentIteration == 0 && m_currentIteration+1 < blockSize.x()*blockSize.y()) 599 log << TestLog::Message << "Note: not logging further images unless reference comparison fails" << TestLog::EndMessage; 600 601 m_currentIteration++; 602 603 if (m_currentIteration >= blockSize.x()*blockSize.y()) 604 { 605 DE_ASSERT(m_currentIteration == blockSize.x()*blockSize.y()); 606 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 607 return STOP; 608 } 609 return CONTINUE; 610 } 611 612 } // Functional 613 } // gles3 614 } // deqp 615