1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2016 Samsung Electronics Co., Ltd. 7 * Copyright 2014 The Android Open Source Project 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Mipmapping tests. 24 *//*--------------------------------------------------------------------*/ 25 26#include "vktTextureMipmapTests.hpp" 27 28#include "deRandom.hpp" 29#include "deString.h" 30#include "gluShaderUtil.hpp" 31#include "gluTextureTestUtil.hpp" 32#include "tcuMatrix.hpp" 33#include "tcuMatrixUtil.hpp" 34#include "tcuPixelFormat.hpp" 35#include "tcuTexLookupVerifier.hpp" 36#include "tcuTextureUtil.hpp" 37#include "tcuVectorUtil.hpp" 38#include "vkImageUtil.hpp" 39#include "vktTestGroupUtil.hpp" 40#include "vktTextureTestUtil.hpp" 41 42using namespace vk; 43 44namespace vkt 45{ 46namespace texture 47{ 48namespace 49{ 50 51using std::string; 52using std::vector; 53using tcu::TestLog; 54using tcu::Vec2; 55using tcu::Vec3; 56using tcu::Vec4; 57using tcu::IVec4; 58using tcu::Sampler; 59using tcu::TextureFormat; 60using namespace texture::util; 61using namespace glu::TextureTestUtil; 62 63float getMinLodForCell (int cellNdx) 64{ 65 static const float s_values[] = 66 { 67 1.0f, 68 3.5f, 69 2.0f, 70 -2.0f, 71 0.0f, 72 3.0f, 73 10.0f, 74 4.8f, 75 5.8f, 76 5.7f, 77 -1.9f, 78 4.0f, 79 6.5f, 80 7.1f, 81 -1e10, 82 1000.f 83 }; 84 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)]; 85} 86 87float getMaxLodForCell (int cellNdx) 88{ 89 static const float s_values[] = 90 { 91 0.0f, 92 0.2f, 93 0.7f, 94 0.4f, 95 1.3f, 96 0.0f, 97 0.5f, 98 1.2f, 99 -2.0f, 100 1.0f, 101 0.1f, 102 0.3f, 103 2.7f, 104 1.2f, 105 10.0f, 106 -1000.f, 107 1e10f 108 }; 109 return s_values[cellNdx % DE_LENGTH_OF_ARRAY(s_values)]; 110} 111 112enum CoordType 113{ 114 COORDTYPE_BASIC, //!< texCoord = translateScale(position). 115 COORDTYPE_BASIC_BIAS, //!< Like basic, but with bias values. 116 COORDTYPE_AFFINE, //!< texCoord = translateScaleRotateShear(position). 117 COORDTYPE_PROJECTED, //!< Projected coordinates, w != 1 118 119 COORDTYPE_LAST 120}; 121 122struct TextureMipmapCommonTestCaseParameters 123{ 124 TextureMipmapCommonTestCaseParameters (void); 125 CoordType coordType; 126 const char* minFilterName; 127}; 128 129TextureMipmapCommonTestCaseParameters::TextureMipmapCommonTestCaseParameters (void) 130 : coordType (COORDTYPE_BASIC) 131 , minFilterName (NULL) 132{ 133} 134 135struct Texture2DMipmapTestCaseParameters : public Texture2DTestCaseParameters, public TextureMipmapCommonTestCaseParameters 136{ 137}; 138 139struct TextureCubeMipmapTestCaseParameters : public TextureCubeTestCaseParameters, public TextureMipmapCommonTestCaseParameters 140{ 141}; 142 143struct Texture3DMipmapTestCaseParameters : public Texture3DTestCaseParameters, public TextureMipmapCommonTestCaseParameters 144{ 145}; 146 147// Texture2DMipmapTestInstance 148class Texture2DMipmapTestInstance : public TestInstance 149{ 150public: 151 typedef Texture2DMipmapTestCaseParameters ParameterType; 152 153 Texture2DMipmapTestInstance (Context& context, const ParameterType& testParameters); 154 ~Texture2DMipmapTestInstance (void); 155 156 virtual tcu::TestStatus iterate (void); 157 158private: 159 Texture2DMipmapTestInstance (const Texture2DMipmapTestInstance& other); 160 Texture2DMipmapTestInstance& operator= (const Texture2DMipmapTestInstance& other); 161 162 const ParameterType m_testParameters; 163 TestTexture2DSp m_texture; 164 TextureRenderer m_renderer; 165}; 166 167Texture2DMipmapTestInstance::Texture2DMipmapTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters) 168 : TestInstance (context) 169 , m_testParameters (testParameters) 170 , m_renderer (context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4) 171{ 172 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT)); 173 174 m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height)); 175 176 const int numLevels = deLog2Floor32(de::max(m_testParameters.width, m_testParameters.height))+1; 177 178 // Fill texture with colored grid. 179 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 180 { 181 const deUint32 step = 0xff / (numLevels-1); 182 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 183 const deUint32 dec = 0xff - inc; 184 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff; 185 const deUint32 color = 0xff000000 | rgb; 186 187 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()); 188 } 189 190 // Upload texture data. 191 m_renderer.add2DTexture(m_texture); 192} 193 194Texture2DMipmapTestInstance::~Texture2DMipmapTestInstance (void) 195{ 196} 197 198static void getBasicTexCoord2D (std::vector<float>& dst, int cellNdx) 199{ 200 static const struct 201 { 202 const Vec2 bottomLeft; 203 const Vec2 topRight; 204 } s_basicCoords[] = 205 { 206 { Vec2(-0.1f, 0.1f), Vec2( 0.8f, 1.0f) }, 207 { Vec2(-0.3f, -0.6f), Vec2( 0.7f, 0.4f) }, 208 { Vec2(-0.3f, 0.6f), Vec2( 0.7f, -0.9f) }, 209 { Vec2(-0.8f, 0.6f), Vec2( 0.7f, -0.9f) }, 210 211 { Vec2(-0.5f, -0.5f), Vec2( 1.5f, 1.5f) }, 212 { Vec2( 1.0f, -1.0f), Vec2(-1.3f, 1.0f) }, 213 { Vec2( 1.2f, -1.0f), Vec2(-1.3f, 1.6f) }, 214 { Vec2( 2.2f, -1.1f), Vec2(-1.3f, 0.8f) }, 215 216 { Vec2(-1.5f, 1.6f), Vec2( 1.7f, -1.4f) }, 217 { Vec2( 2.0f, 1.6f), Vec2( 2.3f, -1.4f) }, 218 { Vec2( 1.3f, -2.6f), Vec2(-2.7f, 2.9f) }, 219 { Vec2(-0.8f, -6.6f), Vec2( 6.0f, -0.9f) }, 220 221 { Vec2( -8.0f, 9.0f), Vec2( 8.3f, -7.0f) }, 222 { Vec2(-16.0f, 10.0f), Vec2( 18.3f, 24.0f) }, 223 { Vec2( 30.2f, 55.0f), Vec2(-24.3f, -1.6f) }, 224 { Vec2(-33.2f, 64.1f), Vec2( 32.1f, -64.1f) }, 225 }; 226 227 DE_ASSERT(de::inBounds(cellNdx, 0, DE_LENGTH_OF_ARRAY(s_basicCoords))); 228 229 const Vec2& bottomLeft = s_basicCoords[cellNdx].bottomLeft; 230 const Vec2& topRight = s_basicCoords[cellNdx].topRight; 231 232 computeQuadTexCoord2D(dst, bottomLeft, topRight); 233} 234 235static void getAffineTexCoord2D (std::vector<float>& dst, int cellNdx) 236{ 237 // Use basic coords as base. 238 getBasicTexCoord2D(dst, cellNdx); 239 240 // Rotate based on cell index. 241 const float angle = 2.0f*DE_PI * ((float)cellNdx / 16.0f); 242 const tcu::Mat2 rotMatrix = tcu::rotationMatrix(angle); 243 244 // Second and third row are sheared. 245 const float shearX = de::inRange(cellNdx, 4, 11) ? (float)(15-cellNdx) / 16.0f : 0.0f; 246 const tcu::Mat2 shearMatrix = tcu::shearMatrix(tcu::Vec2(shearX, 0.0f)); 247 248 const tcu::Mat2 transform = rotMatrix * shearMatrix; 249 const Vec2 p0 = transform * Vec2(dst[0], dst[1]); 250 const Vec2 p1 = transform * Vec2(dst[2], dst[3]); 251 const Vec2 p2 = transform * Vec2(dst[4], dst[5]); 252 const Vec2 p3 = transform * Vec2(dst[6], dst[7]); 253 254 dst[0] = p0.x(); dst[1] = p0.y(); 255 dst[2] = p1.x(); dst[3] = p1.y(); 256 dst[4] = p2.x(); dst[5] = p2.y(); 257 dst[6] = p3.x(); dst[7] = p3.y(); 258} 259 260tcu::TestStatus Texture2DMipmapTestInstance::iterate (void) 261{ 262 const Sampler::FilterMode magFilter = Sampler::NEAREST; 263 const int viewportWidth = m_renderer.getRenderWidth(); 264 const int viewportHeight = m_renderer.getRenderHeight(); 265 266 ReferenceParams refParams (TEXTURETYPE_2D); 267 vector<float> texCoord; 268 269 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED; 270 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS; 271 272 tcu::Surface renderedFrame (viewportWidth, viewportHeight); 273 274 // Viewport is divided into 4x4 grid. 275 const int gridWidth = 4; 276 const int gridHeight = 4; 277 const int cellWidth = viewportWidth / gridWidth; 278 const int cellHeight = viewportHeight / gridHeight; 279 280 // Sampling parameters. 281 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter); 282 refParams.samplerType = getSamplerType(vk::mapVkFormat(m_testParameters.format)); 283 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0); 284 refParams.lodMode = LODMODE_EXACT; // Use ideal lod. 285 286 // Bias values. 287 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f }; 288 289 // Projection values. 290 static const Vec4 s_projections[] = 291 { 292 Vec4(1.2f, 1.0f, 0.7f, 1.0f), 293 Vec4(1.3f, 0.8f, 0.6f, 2.0f), 294 Vec4(0.8f, 1.0f, 1.7f, 0.6f), 295 Vec4(1.2f, 1.0f, 1.7f, 1.5f) 296 }; 297 298 // Render cells. 299 for (int gridY = 0; gridY < gridHeight; gridY++) 300 { 301 for (int gridX = 0; gridX < gridWidth; gridX++) 302 { 303 const int curX = cellWidth*gridX; 304 const int curY = cellHeight*gridY; 305 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 306 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 307 const int cellNdx = gridY*gridWidth + gridX; 308 309 // Compute texcoord. 310 switch (m_testParameters.coordType) 311 { 312 case COORDTYPE_BASIC_BIAS: // Fall-through. 313 case COORDTYPE_PROJECTED: 314 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break; 315 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break; 316 default: DE_ASSERT(DE_FALSE); 317 } 318 319 if (isProjected) 320 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 321 322 if (useLodBias) 323 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 324 325 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH); 326 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams); 327 } 328 } 329 330 // Compare and log. 331 { 332 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 333 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]); 334 const bool isTrilinear = m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR; 335 tcu::Surface referenceFrame (viewportWidth, viewportHeight); 336 tcu::Surface errorMask (viewportWidth, viewportHeight); 337 tcu::LookupPrecision lookupPrec; 338 tcu::LodPrecision lodPrec; 339 int numFailedPixels = 0; 340 341 lookupPrec.coordBits = tcu::IVec3(20, 20, 0); 342 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored. 343 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0))); 344 lookupPrec.colorMask = getCompareMask(pixelFormat); 345 lodPrec.derivateBits = 10; 346 lodPrec.lodBits = isProjected ? 6 : 8; 347 348 for (int gridY = 0; gridY < gridHeight; gridY++) 349 { 350 for (int gridX = 0; gridX < gridWidth; gridX++) 351 { 352 const int curX = cellWidth*gridX; 353 const int curY = cellHeight*gridY; 354 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 355 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 356 const int cellNdx = gridY*gridWidth + gridX; 357 358 // Compute texcoord. 359 switch (m_testParameters.coordType) 360 { 361 case COORDTYPE_BASIC_BIAS: // Fall-through. 362 case COORDTYPE_PROJECTED: 363 case COORDTYPE_BASIC: getBasicTexCoord2D (texCoord, cellNdx); break; 364 case COORDTYPE_AFFINE: getAffineTexCoord2D (texCoord, cellNdx); break; 365 default: DE_ASSERT(DE_FALSE); 366 } 367 368 if (isProjected) 369 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 370 371 if (useLodBias) 372 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 373 374 // Render ideal result 375 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH), 376 m_texture->getTexture(), &texCoord[0], refParams); 377 378 // Compare this cell 379 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 380 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 381 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 382 m_texture->getTexture(), &texCoord[0], refParams, 383 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog()); 384 } 385 } 386 387 if (numFailedPixels > 0) 388 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 389 390 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result") 391 << TestLog::Image("Rendered", "Rendered image", renderedFrame); 392 393 if (numFailedPixels > 0) 394 { 395 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 396 << TestLog::Image("ErrorMask", "Error mask", errorMask); 397 } 398 399 m_context.getTestContext().getLog() << TestLog::EndImageSet; 400 401 { 402 const bool isOk = numFailedPixels == 0; 403 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail"); 404 } 405 } 406} 407 408// TextureCubeMipmapTestInstance 409class TextureCubeMipmapTestInstance : public TestInstance 410{ 411public: 412 typedef TextureCubeMipmapTestCaseParameters ParameterType; 413 414 TextureCubeMipmapTestInstance (Context& context, const ParameterType& testParameters); 415 ~TextureCubeMipmapTestInstance (void); 416 417 virtual tcu::TestStatus iterate (void); 418 419private: 420 TextureCubeMipmapTestInstance (const TextureCubeMipmapTestInstance& other); 421 TextureCubeMipmapTestInstance& operator= (const TextureCubeMipmapTestInstance& other); 422 423 const ParameterType m_testParameters; 424 TestTextureCubeSp m_texture; 425 TextureRenderer m_renderer; 426}; 427 428TextureCubeMipmapTestInstance::TextureCubeMipmapTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters) 429 : TestInstance (context) 430 , m_testParameters (testParameters) 431 , m_renderer (context, m_testParameters.sampleCount, m_testParameters.size*2, m_testParameters.size*2) 432{ 433 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT)); 434 435 m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(m_testParameters.format), m_testParameters.size)); 436 437 const int numLevels = deLog2Floor32(m_testParameters.size)+1; 438 439 // Fill texture with colored grid. 440 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 441 { 442 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 443 { 444 const deUint32 step = 0xff / (numLevels-1); 445 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 446 const deUint32 dec = 0xff - inc; 447 deUint32 rgb = 0; 448 449 switch (faceNdx) 450 { 451 case 0: rgb = (inc << 16) | (dec << 8) | 255; break; 452 case 1: rgb = (255 << 16) | (inc << 8) | dec; break; 453 case 2: rgb = (dec << 16) | (255 << 8) | inc; break; 454 case 3: rgb = (dec << 16) | (inc << 8) | 255; break; 455 case 4: rgb = (255 << 16) | (dec << 8) | inc; break; 456 case 5: rgb = (inc << 16) | (255 << 8) | dec; break; 457 } 458 459 const deUint32 color = 0xff000000 | rgb; 460 tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec()); 461 } 462 } 463 464 m_renderer.addCubeTexture(m_texture); 465} 466 467TextureCubeMipmapTestInstance::~TextureCubeMipmapTestInstance (void) 468{ 469} 470 471static void randomPartition (vector<IVec4>& dst, de::Random& rnd, int x, int y, int width, int height) 472{ 473 const int minWidth = 8; 474 const int minHeight = 8; 475 476 const bool partition = rnd.getFloat() > 0.4f; 477 const bool partitionX = partition && width > minWidth && rnd.getBool(); 478 const bool partitionY = partition && height > minHeight && !partitionX; 479 480 if (partitionX) 481 { 482 const int split = width/2 + rnd.getInt(-width/4, +width/4); 483 randomPartition(dst, rnd, x, y, split, height); 484 randomPartition(dst, rnd, x+split, y, width-split, height); 485 } 486 else if (partitionY) 487 { 488 const int split = height/2 + rnd.getInt(-height/4, +height/4); 489 randomPartition(dst, rnd, x, y, width, split); 490 randomPartition(dst, rnd, x, y+split, width, height-split); 491 } 492 else 493 dst.push_back(IVec4(x, y, width, height)); 494} 495 496static void computeGridLayout (vector<IVec4>& dst, int width, int height) 497{ 498 de::Random rnd(7); 499 randomPartition(dst, rnd, 0, 0, width, height); 500} 501 502tcu::TestStatus TextureCubeMipmapTestInstance::iterate (void) 503{ 504 const int viewportWidth = m_renderer.getRenderWidth(); 505 const int viewportHeight = m_renderer.getRenderHeight(); 506 507 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED; 508 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS; 509 510 ReferenceParams refParams (TEXTURETYPE_CUBE); 511 vector<float> texCoord; 512 tcu::Surface renderedFrame (viewportWidth, viewportHeight); 513 514 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter); 515 refParams.samplerType = getSamplerType(vk::mapVkFormat(m_testParameters.format)); 516 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0); 517 refParams.lodMode = LODMODE_EXACT; // Use ideal lod. 518 519 // Compute grid. 520 vector<IVec4> gridLayout; 521 computeGridLayout(gridLayout, viewportWidth, viewportHeight); 522 523 // Bias values. 524 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f }; 525 526 // Projection values \note Less agressive than in 2D case due to smaller quads. 527 static const Vec4 s_projections[] = 528 { 529 Vec4(1.2f, 1.0f, 0.7f, 1.0f), 530 Vec4(1.3f, 0.8f, 0.6f, 1.1f), 531 Vec4(0.8f, 1.0f, 1.2f, 0.8f), 532 Vec4(1.2f, 1.0f, 1.3f, 0.9f) 533 }; 534 535 // Render with GL 536 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++) 537 { 538 const float curX = (float)gridLayout[cellNdx].x(); 539 const float curY = (float)gridLayout[cellNdx].y(); 540 const float curW = (float)gridLayout[cellNdx].z(); 541 const float curH = (float)gridLayout[cellNdx].w(); 542 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST); 543 544 DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported. 545 computeQuadTexCoordCube(texCoord, cubeFace); 546 547 if (isProjected) 548 { 549 refParams.flags |= ReferenceParams::PROJECTED; 550 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 551 } 552 553 if (useLodBias) 554 { 555 refParams.flags |= ReferenceParams::USE_BIAS; 556 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 557 } 558 559 // Render 560 m_renderer.setViewport(curX, curY, curW, curH); 561 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams); 562 } 563 564 // Render reference and compare 565 { 566 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 567 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]); 568 tcu::Surface referenceFrame (viewportWidth, viewportHeight); 569 tcu::Surface errorMask (viewportWidth, viewportHeight); 570 int numFailedPixels = 0; 571 tcu::LookupPrecision lookupPrec; 572 tcu::LodPrecision lodPrec; 573 574 // Params for rendering reference 575 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, m_testParameters.magFilter); 576 refParams.sampler.seamlessCubeMap = true; 577 refParams.lodMode = LODMODE_EXACT; 578 579 // Comparison parameters 580 lookupPrec.colorMask = getCompareMask(pixelFormat); 581 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, tcu::IVec4(0))); 582 lookupPrec.coordBits = isProjected ? tcu::IVec3(8) : tcu::IVec3(10); 583 lookupPrec.uvwBits = tcu::IVec3(5,5,0); 584 lodPrec.derivateBits = 10; 585 lodPrec.lodBits = isProjected ? 3 : 6; 586 587 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++) 588 { 589 const int curX = gridLayout[cellNdx].x(); 590 const int curY = gridLayout[cellNdx].y(); 591 const int curW = gridLayout[cellNdx].z(); 592 const int curH = gridLayout[cellNdx].w(); 593 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST); 594 595 DE_ASSERT(m_testParameters.coordType != COORDTYPE_AFFINE); // Not supported. 596 computeQuadTexCoordCube(texCoord, cubeFace); 597 598 if (isProjected) 599 { 600 refParams.flags |= ReferenceParams::PROJECTED; 601 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 602 } 603 604 if (useLodBias) 605 { 606 refParams.flags |= ReferenceParams::USE_BIAS; 607 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 608 } 609 610 // Render ideal reference. 611 { 612 tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH); 613 sampleTexture(idealDst, m_texture->getTexture(), &texCoord[0], refParams); 614 } 615 616 // Compare this cell 617 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 618 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 619 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 620 m_texture->getTexture(), &texCoord[0], refParams, 621 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog()); 622 } 623 624 if (numFailedPixels > 0) 625 { 626 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 627 } 628 629 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result") 630 << TestLog::Image("Rendered", "Rendered image", renderedFrame); 631 632 if (numFailedPixels > 0) 633 { 634 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 635 << TestLog::Image("ErrorMask", "Error mask", errorMask); 636 } 637 638 m_context.getTestContext().getLog() << TestLog::EndImageSet; 639 640 { 641 const bool isOk = numFailedPixels == 0; 642 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail"); 643 } 644 } 645} 646 647// Texture3DMipmapTestInstance 648class Texture3DMipmapTestInstance : public TestInstance 649{ 650public: 651 typedef Texture3DMipmapTestCaseParameters ParameterType; 652 653 Texture3DMipmapTestInstance (Context& context, const ParameterType& testParameters); 654 ~Texture3DMipmapTestInstance (void); 655 656 virtual tcu::TestStatus iterate (void); 657 658private: 659 Texture3DMipmapTestInstance (const Texture3DMipmapTestInstance& other); 660 Texture3DMipmapTestInstance& operator= (const Texture3DMipmapTestInstance& other); 661 662 const ParameterType m_testParameters; 663 TestTexture3DSp m_texture; 664 TextureRenderer m_renderer; 665}; 666 667Texture3DMipmapTestInstance::Texture3DMipmapTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters) 668 : TestInstance (context) 669 , m_testParameters (testParameters) 670 , m_renderer (context, testParameters.sampleCount, testParameters.width*4, testParameters.height*4) 671{ 672 TCU_CHECK_INTERNAL(!(m_testParameters.coordType == COORDTYPE_PROJECTED && m_testParameters.sampleCount != VK_SAMPLE_COUNT_1_BIT)); 673 674 const tcu::TextureFormat& texFmt = mapVkFormat(testParameters.format); 675 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt); 676 const tcu::Vec4& cScale = fmtInfo.lookupScale; 677 const tcu::Vec4& cBias = fmtInfo.lookupBias; 678 const int numLevels = deLog2Floor32(de::max(de::max(testParameters.width, testParameters.height), testParameters.depth))+1; 679 680 m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(m_testParameters.format), m_testParameters.width, m_testParameters.height, m_testParameters.depth)); 681 682 // Fill texture with colored grid. 683 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 684 { 685 const deUint32 step = 0xff / (numLevels-1); 686 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 687 const deUint32 dec = 0xff - inc; 688 const deUint32 rgb = (0xff << 16) | (dec << 8) | inc; 689 const deUint32 color = 0xff000000 | rgb; 690 691 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias); 692 } 693 694 m_renderer.add3DTexture(m_texture); 695} 696 697Texture3DMipmapTestInstance::~Texture3DMipmapTestInstance (void) 698{ 699} 700 701static void getBasicTexCoord3D (std::vector<float>& dst, int cellNdx) 702{ 703 static const struct 704 { 705 const float sScale; 706 const float sBias; 707 const float tScale; 708 const float tBias; 709 const float rScale; 710 const float rBias; 711 } s_params[] = 712 { 713 // sScale sBias tScale tBias rScale rBias 714 { 0.9f, -0.1f, 0.7f, 0.3f, 0.8f, 0.9f }, 715 { 1.2f, -0.1f, 1.1f, 0.3f, 1.0f, 0.9f }, 716 { 1.5f, 0.7f, 0.9f, -0.3f, 1.1f, 0.1f }, 717 { 1.2f, 0.7f, -2.3f, -0.3f, 1.1f, 0.2f }, 718 { 1.1f, 0.8f, -1.3f, -0.3f, 2.9f, 0.9f }, 719 { 3.4f, 0.8f, 4.0f, 0.0f, -3.3f, -1.0f }, 720 { -3.4f, -0.1f, -4.0f, 0.0f, -5.1f, 1.0f }, 721 { -4.0f, -0.1f, 3.4f, 0.1f, 5.7f, 0.0f }, 722 { -5.6f, 0.0f, 0.5f, 1.2f, 3.9f, 4.0f }, 723 { 5.0f, -2.0f, 3.1f, 1.2f, 5.1f, 0.2f }, 724 { 2.5f, -2.0f, 6.3f, 3.0f, 5.1f, 0.2f }, 725 { -8.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f }, 726 { 3.8f, 0.0f, 9.7f, 1.0f, 7.0f, 0.7f }, 727 { 13.3f, 0.0f, 7.1f, 3.0f, 2.0f, 0.2f }, 728 { 16.0f, 8.0f, 12.7f, 1.0f, 17.1f, 0.7f }, 729 { 15.3f, 0.0f, 20.1f, 3.0f, 33.0f, 3.2f } 730 }; 731 732 const float sScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sScale; 733 const float sBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].sBias; 734 const float tScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tScale; 735 const float tBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].tBias; 736 const float rScale = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rScale; 737 const float rBias = s_params[cellNdx%DE_LENGTH_OF_ARRAY(s_params)].rBias; 738 739 dst.resize(3*4); 740 741 dst[0] = sBias; dst[ 1] = tBias; dst[ 2] = rBias; 742 dst[3] = sBias; dst[ 4] = tBias+tScale; dst[ 5] = rBias+rScale*0.5f; 743 dst[6] = sBias+sScale; dst[ 7] = tBias; dst[ 8] = rBias+rScale*0.5f; 744 dst[9] = sBias+sScale; dst[10] = tBias+tScale; dst[11] = rBias+rScale; 745} 746 747static void getAffineTexCoord3D (std::vector<float>& dst, int cellNdx) 748{ 749 // Use basic coords as base. 750 getBasicTexCoord3D(dst, cellNdx); 751 752 // Rotate based on cell index. 753 const float angleX = 0.0f + 2.0f*DE_PI * ((float)cellNdx / 16.0f); 754 const float angleY = 1.0f + 2.0f*DE_PI * ((float)cellNdx / 32.0f); 755 const tcu::Mat3 rotMatrix = tcu::rotationMatrixX(angleX) * tcu::rotationMatrixY(angleY); 756 757 const Vec3 p0 = rotMatrix * Vec3(dst[0], dst[ 1], dst[ 2]); 758 const Vec3 p1 = rotMatrix * Vec3(dst[3], dst[ 4], dst[ 5]); 759 const Vec3 p2 = rotMatrix * Vec3(dst[6], dst[ 7], dst[ 8]); 760 const Vec3 p3 = rotMatrix * Vec3(dst[9], dst[10], dst[11]); 761 762 dst[0] = p0.x(); dst[ 1] = p0.y(); dst[ 2] = p0.z(); 763 dst[3] = p1.x(); dst[ 4] = p1.y(); dst[ 5] = p1.z(); 764 dst[6] = p2.x(); dst[ 7] = p2.y(); dst[ 8] = p2.z(); 765 dst[9] = p3.x(); dst[10] = p3.y(); dst[11] = p3.z(); 766} 767 768tcu::TestStatus Texture3DMipmapTestInstance::iterate (void) 769{ 770 const tcu::TextureFormat& texFmt = m_texture->getTextureFormat(); 771 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt); 772 const Sampler::FilterMode magFilter = Sampler::NEAREST; 773 const int viewportWidth = m_renderer.getRenderWidth(); 774 const int viewportHeight = m_renderer.getRenderHeight(); 775 776 const bool isProjected = m_testParameters.coordType == COORDTYPE_PROJECTED; 777 const bool useLodBias = m_testParameters.coordType == COORDTYPE_BASIC_BIAS; 778 779 // Viewport is divided into 4x4 grid. 780 const int gridWidth = 4; 781 const int gridHeight = 4; 782 const int cellWidth = viewportWidth / gridWidth; 783 const int cellHeight = viewportHeight / gridHeight; 784 785 ReferenceParams refParams (TEXTURETYPE_3D); 786 787 tcu::Surface renderedFrame (viewportWidth, viewportHeight); 788 vector<float> texCoord; 789 790 // Sampling parameters. 791 refParams.sampler = util::createSampler(m_testParameters.wrapS, m_testParameters.wrapT, m_testParameters.minFilter, magFilter); 792 refParams.samplerType = getSamplerType(texFmt); 793 794 refParams.colorBias = fmtInfo.lookupBias; 795 refParams.colorScale = fmtInfo.lookupScale; 796 refParams.flags = (isProjected ? ReferenceParams::PROJECTED : 0) | (useLodBias ? ReferenceParams::USE_BIAS : 0); 797 798 // Bias values. 799 static const float s_bias[] = { 1.0f, -2.0f, 0.8f, -0.5f, 1.5f, 0.9f, 2.0f, 4.0f }; 800 801 // Projection values. 802 static const Vec4 s_projections[] = 803 { 804 Vec4(1.2f, 1.0f, 0.7f, 1.0f), 805 Vec4(1.3f, 0.8f, 0.6f, 2.0f), 806 Vec4(0.8f, 1.0f, 1.7f, 0.6f), 807 Vec4(1.2f, 1.0f, 1.7f, 1.5f) 808 }; 809 810 // Render cells. 811 for (int gridY = 0; gridY < gridHeight; gridY++) 812 { 813 for (int gridX = 0; gridX < gridWidth; gridX++) 814 { 815 const int curX = cellWidth*gridX; 816 const int curY = cellHeight*gridY; 817 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 818 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 819 const int cellNdx = gridY*gridWidth + gridX; 820 821 // Compute texcoord. 822 switch (m_testParameters.coordType) 823 { 824 case COORDTYPE_BASIC_BIAS: // Fall-through. 825 case COORDTYPE_PROJECTED: 826 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break; 827 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break; 828 default: DE_ASSERT(DE_FALSE); 829 } 830 831 // Set projection. 832 if (isProjected) 833 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 834 835 // Set LOD bias. 836 if (useLodBias) 837 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 838 839 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH); 840 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams); 841 } 842 } 843 844 // Compare and log 845 { 846 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 847 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]); 848 const bool isTrilinear = m_testParameters.minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_testParameters.minFilter == Sampler::LINEAR_MIPMAP_LINEAR; 849 tcu::Surface referenceFrame (viewportWidth, viewportHeight); 850 tcu::Surface errorMask (viewportWidth, viewportHeight); 851 tcu::LookupPrecision lookupPrec; 852 tcu::LodPrecision lodPrec; 853 int numFailedPixels = 0; 854 855 lookupPrec.coordBits = tcu::IVec3(20, 20, 20); 856 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored. 857 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0))); 858 lookupPrec.colorMask = getCompareMask(pixelFormat); 859 lodPrec.derivateBits = 10; 860 lodPrec.lodBits = isProjected ? 6 : 8; 861 862 for (int gridY = 0; gridY < gridHeight; gridY++) 863 { 864 for (int gridX = 0; gridX < gridWidth; gridX++) 865 { 866 const int curX = cellWidth*gridX; 867 const int curY = cellHeight*gridY; 868 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 869 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 870 const int cellNdx = gridY*gridWidth + gridX; 871 872 switch (m_testParameters.coordType) 873 { 874 case COORDTYPE_BASIC_BIAS: // Fall-through. 875 case COORDTYPE_PROJECTED: 876 case COORDTYPE_BASIC: getBasicTexCoord3D (texCoord, cellNdx); break; 877 case COORDTYPE_AFFINE: getAffineTexCoord3D (texCoord, cellNdx); break; 878 default: DE_ASSERT(DE_FALSE); 879 } 880 881 if (isProjected) 882 refParams.w = s_projections[cellNdx % DE_LENGTH_OF_ARRAY(s_projections)]; 883 884 if (useLodBias) 885 refParams.bias = s_bias[cellNdx % DE_LENGTH_OF_ARRAY(s_bias)]; 886 887 // Render ideal result 888 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH), 889 m_texture->getTexture(), &texCoord[0], refParams); 890 891 // Compare this cell 892 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 893 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 894 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 895 m_texture->getTexture(), &texCoord[0], refParams, 896 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog()); 897 } 898 } 899 900 if (numFailedPixels > 0) 901 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 902 903 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result") 904 << TestLog::Image("Rendered", "Rendered image", renderedFrame); 905 906 if (numFailedPixels > 0) 907 { 908 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 909 << TestLog::Image("ErrorMask", "Error mask", errorMask); 910 } 911 912 m_context.getTestContext().getLog() << TestLog::EndImageSet; 913 914 { 915 const bool isOk = numFailedPixels == 0; 916 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail"); 917 } 918 } 919} 920 921// Texture2DLodControlTestInstance 922class Texture2DLodControlTestInstance : public TestInstance 923{ 924public: 925 typedef Texture2DMipmapTestCaseParameters ParameterType; 926 927 Texture2DLodControlTestInstance (Context& context, const ParameterType& testParameters); 928 ~Texture2DLodControlTestInstance (void); 929 930 virtual tcu::TestStatus iterate (void); 931 932protected: 933 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = 0; 934 935 const int m_texWidth; 936 const int m_texHeight; 937 938private: 939 Texture2DLodControlTestInstance (const Texture2DLodControlTestInstance& other); 940 Texture2DLodControlTestInstance& operator= (const Texture2DLodControlTestInstance& other); 941 942 const ParameterType m_testParameters; 943 tcu::Sampler::FilterMode m_minFilter; 944 TestTexture2DSp m_texture; 945 TextureRenderer m_renderer; 946}; 947 948Texture2DLodControlTestInstance::Texture2DLodControlTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters) 949 : TestInstance (context) 950 , m_texWidth (64) //64 951 , m_texHeight (64)//64 952 , m_testParameters (testParameters) 953 , m_minFilter (testParameters.minFilter) 954 , m_texture (DE_NULL) 955 , m_renderer (context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4) 956{ 957 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; 958 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1; 959 960 m_texture = TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(format), m_texWidth, m_texHeight)); 961 962 // Fill texture with colored grid. 963 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 964 { 965 const deUint32 step = 0xff / (numLevels-1); 966 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 967 const deUint32 dec = 0xff - inc; 968 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff; 969 const deUint32 color = 0xff000000 | rgb; 970 971 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()); 972 } 973 974 m_renderer.add2DTexture(m_texture); 975} 976 977Texture2DLodControlTestInstance::~Texture2DLodControlTestInstance (void) 978{ 979} 980 981tcu::TestStatus Texture2DLodControlTestInstance::iterate (void) 982{ 983 const tcu::Sampler::WrapMode wrapS = Sampler::REPEAT_GL; 984 const tcu::Sampler::WrapMode wrapT = Sampler::REPEAT_GL; 985 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST; 986 987 const tcu::Texture2D& refTexture = m_texture->getTexture(); 988 989 const int viewportWidth = m_renderer.getRenderWidth(); 990 const int viewportHeight = m_renderer.getRenderHeight(); 991 992 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter); 993 994 ReferenceParams refParams (TEXTURETYPE_2D, sampler); 995 vector<float> texCoord; 996 tcu::Surface renderedFrame (viewportWidth, viewportHeight); 997 998 // Viewport is divided into 4x4 grid. 999 const int gridWidth = 4; 1000 const int gridHeight = 4; 1001 const int cellWidth = viewportWidth / gridWidth; 1002 const int cellHeight = viewportHeight / gridHeight; 1003 1004 refParams.maxLevel = deLog2Floor32(de::max(m_texWidth, m_texHeight)); 1005 1006 // Render cells. 1007 for (int gridY = 0; gridY < gridHeight; gridY++) 1008 { 1009 for (int gridX = 0; gridX < gridWidth; gridX++) 1010 { 1011 const int curX = cellWidth*gridX; 1012 const int curY = cellHeight*gridY; 1013 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 1014 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 1015 const int cellNdx = gridY*gridWidth + gridX; 1016 1017 // Compute texcoord. 1018 getBasicTexCoord2D(texCoord, cellNdx); 1019 // Render 1020 getReferenceParams(refParams,cellNdx); 1021 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH); 1022 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel); 1023 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams); 1024 } 1025 } 1026 1027 // Compare and log. 1028 { 1029 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 1030 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]); 1031 const bool isTrilinear = m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR; 1032 tcu::Surface referenceFrame (viewportWidth, viewportHeight); 1033 tcu::Surface errorMask (viewportWidth, viewportHeight); 1034 tcu::LookupPrecision lookupPrec; 1035 tcu::LodPrecision lodPrec; 1036 int numFailedPixels = 0; 1037 1038 lookupPrec.coordBits = tcu::IVec3(20, 20, 0); 1039 lookupPrec.uvwBits = tcu::IVec3(16, 16, 0); // Doesn't really matter since pixels are unicolored. 1040 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0))); 1041 lookupPrec.colorMask = getCompareMask(pixelFormat); 1042 lodPrec.derivateBits = 10; 1043 lodPrec.lodBits = 8; 1044 1045 for (int gridY = 0; gridY < gridHeight; gridY++) 1046 { 1047 for (int gridX = 0; gridX < gridWidth; gridX++) 1048 { 1049 const int curX = cellWidth*gridX; 1050 const int curY = cellHeight*gridY; 1051 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 1052 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 1053 const int cellNdx = gridY*gridWidth + gridX; 1054 1055 getBasicTexCoord2D(texCoord, cellNdx); 1056 getReferenceParams(refParams, cellNdx); 1057 1058 // Render ideal result 1059 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH), 1060 refTexture, &texCoord[0], refParams); 1061 1062 // Compare this cell 1063 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 1064 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 1065 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 1066 m_texture->getTexture(), &texCoord[0], refParams, 1067 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog()); 1068 } 1069 } 1070 1071 if (numFailedPixels > 0) 1072 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 1073 1074 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result") 1075 << TestLog::Image("Rendered", "Rendered image", renderedFrame); 1076 1077 if (numFailedPixels > 0) 1078 { 1079 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 1080 << TestLog::Image("ErrorMask", "Error mask", errorMask); 1081 } 1082 1083 m_context.getTestContext().getLog() << TestLog::EndImageSet; 1084 1085 { 1086 const bool isOk = numFailedPixels == 0; 1087 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail"); 1088 } 1089 } 1090} 1091 1092class Texture2DMinLodTestInstance : public Texture2DLodControlTestInstance 1093{ 1094public: 1095 Texture2DMinLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters) 1096 : Texture2DLodControlTestInstance(context, testParameters) 1097 { 1098 } 1099 1100protected: 1101 void getReferenceParams (ReferenceParams& params, int cellNdx) 1102 { 1103 params.minLod = getMinLodForCell(cellNdx); 1104 } 1105}; 1106 1107class Texture2DMaxLodTestInstance : public Texture2DLodControlTestInstance 1108{ 1109public: 1110 Texture2DMaxLodTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters) 1111 : Texture2DLodControlTestInstance(context, testParameters) 1112 { 1113 } 1114 1115protected: 1116 void getReferenceParams (ReferenceParams& params, int cellNdx) 1117 { 1118 params.maxLod = getMaxLodForCell(cellNdx); 1119 } 1120}; 1121 1122class Texture2DBaseLevelTestInstance : public Texture2DLodControlTestInstance 1123{ 1124public: 1125 Texture2DBaseLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters) 1126 : Texture2DLodControlTestInstance(context, testParameters) 1127 , m_testParam (testParameters) 1128 { 1129 } 1130 1131protected: 1132 const Texture2DMipmapTestCaseParameters m_testParam; 1133 1134 int getBaseLevel (int cellNdx) const 1135 { 1136 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1; 1137 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0xac2f274a) % numLevels; 1138 1139 return baseLevel; 1140 } 1141 1142 void getReferenceParams (ReferenceParams& params, int cellNdx) 1143 { 1144 params.baseLevel = getBaseLevel(cellNdx); 1145 } 1146}; 1147 1148class Texture2DMaxLevelTestInstance : public Texture2DLodControlTestInstance 1149{ 1150public: 1151 Texture2DMaxLevelTestInstance (Context& context, const Texture2DMipmapTestCaseParameters& testParameters) 1152 : Texture2DLodControlTestInstance(context, testParameters) 1153 , m_testParam (testParameters) 1154 { 1155 } 1156 1157protected: 1158 const Texture2DMipmapTestCaseParameters m_testParam; 1159 1160 int getMaxLevel (int cellNdx) const 1161 { 1162 const int numLevels = deLog2Floor32(de::max(m_texWidth, m_texHeight))+1; 1163 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x82cfa4e) % numLevels; 1164 1165 return maxLevel; 1166 } 1167 1168 void getReferenceParams (ReferenceParams& params, int cellNdx) 1169 { 1170 params.maxLevel = getMaxLevel(cellNdx); 1171 } 1172}; 1173 1174// TextureCubeLodControlTestInstance 1175class TextureCubeLodControlTestInstance : public TestInstance 1176{ 1177public: 1178 typedef TextureCubeMipmapTestCaseParameters ParameterType; 1179 1180 TextureCubeLodControlTestInstance (Context& context, const ParameterType& testParameters); 1181 ~TextureCubeLodControlTestInstance (void); 1182 1183 virtual tcu::TestStatus iterate (void); 1184 1185protected: 1186 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL; 1187 1188 const int m_texSize; 1189 1190private: 1191 TextureCubeLodControlTestInstance (const TextureCubeLodControlTestInstance& other); 1192 TextureCubeLodControlTestInstance& operator= (const TextureCubeLodControlTestInstance& other); 1193 1194 const ParameterType m_testParameters; 1195 tcu::Sampler::FilterMode m_minFilter; 1196 TestTextureCubeSp m_texture; 1197 TextureRenderer m_renderer; 1198}; 1199 1200TextureCubeLodControlTestInstance::TextureCubeLodControlTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters) 1201 : TestInstance (context) 1202 , m_texSize (64) 1203 , m_testParameters (testParameters) 1204 , m_minFilter (testParameters.minFilter) 1205 , m_texture (DE_NULL) 1206 , m_renderer (context, testParameters.sampleCount, m_texSize*2, m_texSize*2) 1207{ 1208 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; 1209 const int numLevels = deLog2Floor32(m_texSize)+1; 1210 1211 m_texture = TestTextureCubeSp(new pipeline::TestTextureCube(vk::mapVkFormat(format), m_texSize)); 1212 1213 // Fill texture with colored grid. 1214 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 1215 { 1216 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 1217 { 1218 const deUint32 step = 0xff / (numLevels-1); 1219 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 1220 const deUint32 dec = 0xff - inc; 1221 deUint32 rgb = 0; 1222 1223 switch (faceNdx) 1224 { 1225 case 0: rgb = (inc << 16) | (dec << 8) | 255; break; 1226 case 1: rgb = (255 << 16) | (inc << 8) | dec; break; 1227 case 2: rgb = (dec << 16) | (255 << 8) | inc; break; 1228 case 3: rgb = (dec << 16) | (inc << 8) | 255; break; 1229 case 4: rgb = (255 << 16) | (dec << 8) | inc; break; 1230 case 5: rgb = (inc << 16) | (255 << 8) | dec; break; 1231 } 1232 1233 const deUint32 color = 0xff000000 | rgb; 1234 1235 tcu::clear(m_texture->getLevel(levelNdx, (tcu::CubeFace)faceNdx), tcu::RGBA(color).toVec()); 1236 } 1237 } 1238 1239 m_renderer.addCubeTexture(m_texture); 1240} 1241 1242TextureCubeLodControlTestInstance::~TextureCubeLodControlTestInstance (void) 1243{ 1244} 1245 1246tcu::TestStatus TextureCubeLodControlTestInstance::iterate (void) 1247{ 1248 const tcu::Sampler::WrapMode wrapS = Sampler::CLAMP_TO_EDGE; 1249 const tcu::Sampler::WrapMode wrapT = Sampler::CLAMP_TO_EDGE; 1250 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST; 1251 1252 const tcu::TextureCube& refTexture = m_texture->getTexture(); 1253 const int viewportWidth = m_renderer.getRenderWidth(); 1254 const int viewportHeight = m_renderer.getRenderHeight(); 1255 1256 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter); 1257 ReferenceParams refParams (TEXTURETYPE_CUBE, sampler); 1258 vector<float> texCoord; 1259 tcu::Surface renderedFrame (viewportWidth, viewportHeight); 1260 1261 refParams.maxLevel = deLog2Floor32(m_texSize); 1262 1263 // Compute grid. 1264 vector<tcu::IVec4> gridLayout; 1265 computeGridLayout(gridLayout, viewportWidth, viewportHeight); 1266 1267 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++) 1268 { 1269 const int curX = gridLayout[cellNdx].x(); 1270 const int curY = gridLayout[cellNdx].y(); 1271 const int curW = gridLayout[cellNdx].z(); 1272 const int curH = gridLayout[cellNdx].w(); 1273 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST); 1274 1275 computeQuadTexCoordCube(texCoord, cubeFace); 1276 getReferenceParams(refParams, cellNdx); 1277 1278 // Render with GL. 1279 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH); 1280 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel); 1281 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams); 1282 } 1283 1284 // Render reference and compare 1285 { 1286 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 1287 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]); 1288 tcu::Surface referenceFrame (viewportWidth, viewportHeight); 1289 tcu::Surface errorMask (viewportWidth, viewportHeight); 1290 int numFailedPixels = 0; 1291 tcu::LookupPrecision lookupPrec; 1292 tcu::LodPrecision lodPrec; 1293 1294 // Params for rendering reference 1295 refParams.sampler = util::createSampler(wrapS, wrapT, m_testParameters.minFilter, magFilter); 1296 refParams.sampler.seamlessCubeMap = true; 1297 refParams.lodMode = LODMODE_EXACT; 1298 1299 // Comparison parameters 1300 lookupPrec.colorMask = getCompareMask(pixelFormat); 1301 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat)-2, IVec4(0))); 1302 lookupPrec.coordBits = tcu::IVec3(10); 1303 lookupPrec.uvwBits = tcu::IVec3(5,5,0); 1304 lodPrec.derivateBits = 10; 1305 lodPrec.lodBits = 6; 1306 1307 for (int cellNdx = 0; cellNdx < (int)gridLayout.size(); cellNdx++) 1308 { 1309 const int curX = gridLayout[cellNdx].x(); 1310 const int curY = gridLayout[cellNdx].y(); 1311 const int curW = gridLayout[cellNdx].z(); 1312 const int curH = gridLayout[cellNdx].w(); 1313 const tcu::CubeFace cubeFace = (tcu::CubeFace)(cellNdx % tcu::CUBEFACE_LAST); 1314 1315 computeQuadTexCoordCube(texCoord, cubeFace); 1316 getReferenceParams(refParams, cellNdx); 1317 1318 // Render ideal reference. 1319 { 1320 tcu::SurfaceAccess idealDst(referenceFrame, pixelFormat, curX, curY, curW, curH); 1321 sampleTexture(idealDst, refTexture, &texCoord[0], refParams); 1322 } 1323 1324 // Compare this cell 1325 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 1326 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 1327 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 1328 m_texture->getTexture(), &texCoord[0], refParams, 1329 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog()); 1330 } 1331 1332 if (numFailedPixels > 0) 1333 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 1334 1335 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result") 1336 << TestLog::Image("Rendered", "Rendered image", renderedFrame); 1337 1338 if (numFailedPixels > 0) 1339 { 1340 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 1341 << TestLog::Image("ErrorMask", "Error mask", errorMask); 1342 } 1343 1344 m_context.getTestContext().getLog() << TestLog::EndImageSet; 1345 1346 { 1347 const bool isOk = numFailedPixels == 0; 1348 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail"); 1349 } 1350 } 1351} 1352 1353class TextureCubeMinLodTestInstance : public TextureCubeLodControlTestInstance 1354{ 1355public: 1356 TextureCubeMinLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters) 1357 : TextureCubeLodControlTestInstance(context, testParameters) 1358 { 1359 } 1360 1361protected: 1362 void getReferenceParams (ReferenceParams& params, int cellNdx) 1363 { 1364 params.minLod = getMinLodForCell(cellNdx); 1365 } 1366}; 1367 1368class TextureCubeMaxLodTestInstance : public TextureCubeLodControlTestInstance 1369{ 1370public: 1371 TextureCubeMaxLodTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters) 1372 : TextureCubeLodControlTestInstance(context, testParameters) 1373 { 1374 } 1375 1376protected: 1377 void getReferenceParams (ReferenceParams& params, int cellNdx) 1378 { 1379 params.maxLod = getMaxLodForCell(cellNdx); 1380 } 1381}; 1382 1383class TextureCubeBaseLevelTestInstance : public TextureCubeLodControlTestInstance 1384{ 1385public: 1386 TextureCubeBaseLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters) 1387 : TextureCubeLodControlTestInstance(context, testParameters) 1388 , m_testParam (testParameters) 1389 { 1390 } 1391 1392protected: 1393 const TextureCubeMipmapTestCaseParameters m_testParam; 1394 1395 int getBaseLevel (int cellNdx) const 1396 { 1397 const int numLevels = deLog2Floor32(m_texSize)+1; 1398 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x23fae13) % numLevels; 1399 1400 return baseLevel; 1401 } 1402 1403 void getReferenceParams (ReferenceParams& params, int cellNdx) 1404 { 1405 params.baseLevel = getBaseLevel(cellNdx); 1406 } 1407}; 1408 1409class TextureCubeMaxLevelTestInstance : public TextureCubeLodControlTestInstance 1410{ 1411public: 1412 TextureCubeMaxLevelTestInstance (Context& context, const TextureCubeMipmapTestCaseParameters& testParameters) 1413 : TextureCubeLodControlTestInstance(context, testParameters) 1414 , m_testParam (testParameters) 1415 { 1416 } 1417 1418protected: 1419 const TextureCubeMipmapTestCaseParameters m_testParam; 1420 int getMaxLevel (int cellNdx) const 1421 { 1422 const int numLevels = deLog2Floor32(m_texSize)+1; 1423 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x974e21) % numLevels; 1424 1425 return maxLevel; 1426 } 1427 1428 void getReferenceParams (ReferenceParams& params, int cellNdx) 1429 { 1430 params.maxLevel = getMaxLevel(cellNdx); 1431 } 1432}; 1433 1434// Texture3DLodControlTestInstance 1435class Texture3DLodControlTestInstance : public TestInstance 1436{ 1437public: 1438 typedef Texture3DMipmapTestCaseParameters ParameterType; 1439 1440 Texture3DLodControlTestInstance (Context& context, const ParameterType& testParameters); 1441 ~Texture3DLodControlTestInstance (void); 1442 1443 virtual tcu::TestStatus iterate (void); 1444 1445protected: 1446 virtual void getReferenceParams (ReferenceParams& params, int cellNdx) = DE_NULL; 1447 1448 const int m_texWidth; 1449 const int m_texHeight; 1450 const int m_texDepth; 1451 1452private: 1453 Texture3DLodControlTestInstance (const Texture3DLodControlTestInstance& other); 1454 Texture3DLodControlTestInstance& operator= (const Texture3DLodControlTestInstance& other); 1455 1456 const ParameterType m_testParameters; 1457 tcu::Sampler::FilterMode m_minFilter; 1458 TestTexture3DSp m_texture; 1459 TextureRenderer m_renderer; 1460}; 1461 1462Texture3DLodControlTestInstance::Texture3DLodControlTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters) 1463 : TestInstance (context) 1464 , m_texWidth (32) 1465 , m_texHeight (32) 1466 , m_texDepth (32) 1467 , m_testParameters (testParameters) 1468 , m_minFilter (testParameters.minFilter) 1469 , m_texture (DE_NULL) 1470 , m_renderer (context, testParameters.sampleCount, m_texWidth*4, m_texHeight*4) 1471{ 1472 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; 1473 tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format)); 1474 const tcu::Vec4& cScale = fmtInfo.lookupScale; 1475 const tcu::Vec4& cBias = fmtInfo.lookupBias; 1476 const int numLevels = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth))+1; 1477 1478 m_texture = TestTexture3DSp(new pipeline::TestTexture3D(vk::mapVkFormat(format), m_texWidth, m_texHeight, m_texDepth)); 1479 1480 // Fill texture with colored grid. 1481 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++) 1482 { 1483 const deUint32 step = 0xff / (numLevels-1); 1484 const deUint32 inc = deClamp32(step*levelNdx, 0x00, 0xff); 1485 const deUint32 dec = 0xff - inc; 1486 const deUint32 rgb = (inc << 16) | (dec << 8) | 0xff; 1487 const deUint32 color = 0xff000000 | rgb; 1488 1489 tcu::clear(m_texture->getLevel(levelNdx, 0), tcu::RGBA(color).toVec()*cScale + cBias); 1490 } 1491 1492 m_renderer.add3DTexture(m_texture); 1493} 1494 1495Texture3DLodControlTestInstance::~Texture3DLodControlTestInstance (void) 1496{ 1497} 1498 1499tcu::TestStatus Texture3DLodControlTestInstance::iterate (void) 1500{ 1501 const tcu::Sampler::WrapMode wrapS = Sampler::CLAMP_TO_EDGE; 1502 const tcu::Sampler::WrapMode wrapT = Sampler::CLAMP_TO_EDGE; 1503 const tcu::Sampler::WrapMode wrapR = Sampler::CLAMP_TO_EDGE; 1504 const tcu::Sampler::FilterMode magFilter = Sampler::NEAREST; 1505 1506 const tcu::Texture3D& refTexture = m_texture->getTexture(); 1507 const tcu::TextureFormat& texFmt = refTexture.getFormat(); 1508 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(texFmt); 1509 const int viewportWidth = m_renderer.getRenderWidth(); 1510 const int viewportHeight = m_renderer.getRenderHeight(); 1511 1512 tcu::Sampler sampler = util::createSampler(wrapS, wrapT, m_minFilter, magFilter); 1513 ReferenceParams refParams (TEXTURETYPE_3D, sampler); 1514 vector<float> texCoord; 1515 tcu::Surface renderedFrame (viewportWidth, viewportHeight); 1516 1517 // Viewport is divided into 4x4 grid. 1518 const int gridWidth = 4; 1519 const int gridHeight = 4; 1520 const int cellWidth = viewportWidth / gridWidth; 1521 const int cellHeight = viewportHeight / gridHeight; 1522 1523 // Sampling parameters. 1524 refParams.sampler = util::createSampler(wrapS, wrapT, wrapR, m_testParameters.minFilter, magFilter); 1525 refParams.samplerType = getSamplerType(texFmt); 1526 refParams.colorBias = fmtInfo.lookupBias; 1527 refParams.colorScale = fmtInfo.lookupScale; 1528 refParams.maxLevel = deLog2Floor32(de::max(de::max(m_texWidth, m_texHeight), m_texDepth)); 1529 1530 // Render cells. 1531 for (int gridY = 0; gridY < gridHeight; gridY++) 1532 { 1533 for (int gridX = 0; gridX < gridWidth; gridX++) 1534 { 1535 const int curX = cellWidth*gridX; 1536 const int curY = cellHeight*gridY; 1537 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 1538 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 1539 const int cellNdx = gridY*gridWidth + gridX; 1540 1541 // Compute texcoord. 1542 getBasicTexCoord3D(texCoord, cellNdx); 1543 1544 getReferenceParams(refParams,cellNdx); 1545 //Render 1546 m_renderer.setViewport((float)curX, (float)curY, (float)curW, (float)curH); 1547 m_renderer.getTextureBinding(0)->updateTextureViewMipLevels(refParams.baseLevel, refParams.maxLevel); 1548 m_renderer.renderQuad(renderedFrame, 0, &texCoord[0], refParams); 1549 } 1550 } 1551 1552 // Compare and log 1553 { 1554 const tcu::IVec4 formatBitDepth = getTextureFormatBitDepth(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM)); 1555 const tcu::PixelFormat pixelFormat (formatBitDepth[0], formatBitDepth[1], formatBitDepth[2], formatBitDepth[3]); 1556 const bool isTrilinear = m_minFilter == Sampler::NEAREST_MIPMAP_LINEAR || m_minFilter == Sampler::LINEAR_MIPMAP_LINEAR; 1557 tcu::Surface referenceFrame (viewportWidth, viewportHeight); 1558 tcu::Surface errorMask (viewportWidth, viewportHeight); 1559 tcu::LookupPrecision lookupPrec; 1560 tcu::LodPrecision lodPrec; 1561 int numFailedPixels = 0; 1562 1563 lookupPrec.coordBits = tcu::IVec3(20, 20, 20); 1564 lookupPrec.uvwBits = tcu::IVec3(16, 16, 16); // Doesn't really matter since pixels are unicolored. 1565 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(max(getBitsVec(pixelFormat) - (isTrilinear ? 2 : 1), tcu::IVec4(0))); 1566 lookupPrec.colorMask = getCompareMask(pixelFormat); 1567 lodPrec.derivateBits = 10; 1568 lodPrec.lodBits = 8; 1569 1570 for (int gridY = 0; gridY < gridHeight; gridY++) 1571 { 1572 for (int gridX = 0; gridX < gridWidth; gridX++) 1573 { 1574 const int curX = cellWidth*gridX; 1575 const int curY = cellHeight*gridY; 1576 const int curW = gridX+1 == gridWidth ? (viewportWidth-curX) : cellWidth; 1577 const int curH = gridY+1 == gridHeight ? (viewportHeight-curY) : cellHeight; 1578 const int cellNdx = gridY*gridWidth + gridX; 1579 1580 getBasicTexCoord3D(texCoord, cellNdx); 1581 getReferenceParams(refParams, cellNdx); 1582 1583 // Render ideal result 1584 sampleTexture(tcu::SurfaceAccess(referenceFrame, pixelFormat, curX, curY, curW, curH), 1585 refTexture, &texCoord[0], refParams); 1586 1587 // Compare this cell 1588 numFailedPixels += computeTextureLookupDiff(tcu::getSubregion(renderedFrame.getAccess(), curX, curY, curW, curH), 1589 tcu::getSubregion(referenceFrame.getAccess(), curX, curY, curW, curH), 1590 tcu::getSubregion(errorMask.getAccess(), curX, curY, curW, curH), 1591 m_texture->getTexture(), &texCoord[0], refParams, 1592 lookupPrec, lodPrec, m_context.getTestContext().getWatchDog()); 1593 } 1594 } 1595 1596 if (numFailedPixels > 0) 1597 { 1598 m_context.getTestContext().getLog() << TestLog::Message << "ERROR: Image verification failed, found " << numFailedPixels << " invalid pixels!" << TestLog::EndMessage; 1599 } 1600 1601 m_context.getTestContext().getLog() << TestLog::ImageSet("Result", "Verification result") 1602 << TestLog::Image("Rendered", "Rendered image", renderedFrame); 1603 1604 if (numFailedPixels > 0) 1605 { 1606 m_context.getTestContext().getLog() << TestLog::Image("Reference", "Ideal reference", referenceFrame) 1607 << TestLog::Image("ErrorMask", "Error mask", errorMask); 1608 } 1609 1610 m_context.getTestContext().getLog() << TestLog::EndImageSet; 1611 1612 { 1613 const bool isOk = numFailedPixels == 0; 1614 return isOk ? tcu::TestStatus::pass("pass") : tcu::TestStatus::fail("fail"); 1615 } 1616 } 1617} 1618 1619class Texture3DMinLodTestInstance : public Texture3DLodControlTestInstance 1620{ 1621public: 1622 Texture3DMinLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters) 1623 : Texture3DLodControlTestInstance(context, testParameters) 1624 { 1625 } 1626 1627protected: 1628 void getReferenceParams (ReferenceParams& params, int cellNdx) 1629 { 1630 params.minLod = getMinLodForCell(cellNdx); 1631 } 1632}; 1633 1634class Texture3DMaxLodTestInstance : public Texture3DLodControlTestInstance 1635{ 1636public: 1637 Texture3DMaxLodTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters) 1638 : Texture3DLodControlTestInstance(context, testParameters) 1639 { 1640 } 1641 1642protected: 1643 void getReferenceParams (ReferenceParams& params, int cellNdx) 1644 { 1645 params.maxLod = getMaxLodForCell(cellNdx); 1646 } 1647}; 1648 1649class Texture3DBaseLevelTestInstance : public Texture3DLodControlTestInstance 1650{ 1651public: 1652 Texture3DBaseLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters) 1653 : Texture3DLodControlTestInstance(context, testParameters) 1654 ,m_testParam (testParameters) 1655 { 1656 } 1657 1658protected: 1659 const Texture3DMipmapTestCaseParameters m_testParam; 1660 1661 int getBaseLevel (int cellNdx) const 1662 { 1663 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1; 1664 const int baseLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x7347e9) % numLevels; 1665 1666 return baseLevel; 1667 } 1668 1669 void getReferenceParams (ReferenceParams& params, int cellNdx) 1670 { 1671 params.baseLevel = getBaseLevel(cellNdx); 1672 } 1673}; 1674 1675class Texture3DMaxLevelTestInstance : public Texture3DLodControlTestInstance 1676{ 1677public: 1678 Texture3DMaxLevelTestInstance (Context& context, const Texture3DMipmapTestCaseParameters& testParameters) 1679 : Texture3DLodControlTestInstance(context, testParameters) 1680 ,m_testParam (testParameters) 1681 { 1682 } 1683 1684protected: 1685 const Texture3DMipmapTestCaseParameters m_testParam; 1686 1687 int getMaxLevel (int cellNdx) const 1688 { 1689 const int numLevels = deLog2Floor32(de::max(m_texWidth, de::max(m_texHeight, m_texDepth)))+1; 1690 const int maxLevel = (deInt32Hash(cellNdx) ^ deStringHash(m_testParam.minFilterName) ^ 0x9111e7) % numLevels; 1691 1692 return maxLevel; 1693 } 1694 1695 void getReferenceParams (ReferenceParams& params, int cellNdx) 1696 { 1697 params.maxLevel = getMaxLevel(cellNdx); 1698 } 1699}; 1700 1701void populateTextureMipmappingTests (tcu::TestCaseGroup* textureMipmappingTests) 1702{ 1703 tcu::TestContext& testCtx = textureMipmappingTests->getTestContext(); 1704 1705 static const struct 1706 { 1707 const char* name; 1708 const Sampler::WrapMode mode; 1709 } wrapModes[] = 1710 { 1711 { "clamp", Sampler::CLAMP_TO_EDGE }, 1712 { "repeat", Sampler::REPEAT_GL }, 1713 { "mirror", Sampler::MIRRORED_REPEAT_GL } 1714 }; 1715 1716 static const struct 1717 { 1718 const char* name; 1719 const Sampler::FilterMode mode; 1720 } minFilterModes[] = 1721 { 1722 { "nearest_nearest", Sampler::NEAREST_MIPMAP_NEAREST }, 1723 { "linear_nearest", Sampler::LINEAR_MIPMAP_NEAREST }, 1724 { "nearest_linear", Sampler::NEAREST_MIPMAP_LINEAR }, 1725 { "linear_linear", Sampler::LINEAR_MIPMAP_LINEAR } 1726 }; 1727 1728 static const struct 1729 { 1730 const char* name; 1731 const Sampler::FilterMode mode; 1732 } magFilterModes[] = 1733 { 1734 { "nearest", Sampler::NEAREST}, 1735 { "linear", Sampler::LINEAR} 1736 }; 1737 1738 1739 static const struct 1740 { 1741 const CoordType type; 1742 const char* name; 1743 const char* desc; 1744 } coordTypes[] = 1745 { 1746 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" }, 1747 { COORDTYPE_AFFINE, "affine", "Mipmapping with affine coordinate transform" }, 1748 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" } 1749 }; 1750 1751 static const struct 1752 { 1753 const char* name; 1754 const int width; 1755 const int height; 1756 } tex2DSizes[] = 1757 { 1758 { DE_NULL, 64, 64 }, // Default. 1759 { "npot", 63, 57 }, 1760 { "non_square", 32, 64 } 1761 }; 1762 1763 static const struct 1764 { 1765 const char* name; 1766 const int width; 1767 const int height; 1768 const int depth; 1769 } tex3DSizes[] = 1770 { 1771 { DE_NULL, 32, 32, 32 }, // Default. 1772 { "npot", 33, 29, 27 } 1773 }; 1774 1775 const int cubeMapSize = 64; 1776 1777 static const struct 1778 { 1779 const CoordType type; 1780 const char* name; 1781 const char* desc; 1782 } cubeCoordTypes[] = 1783 { 1784 { COORDTYPE_BASIC, "basic", "Mipmapping with translated and scaled coordinates" }, 1785 { COORDTYPE_PROJECTED, "projected", "Mipmapping with perspective projection" }, 1786 { COORDTYPE_BASIC_BIAS, "bias", "User-supplied bias value" } 1787 }; 1788 1789 // 2D cases. 1790 { 1791 de::MovePtr<tcu::TestCaseGroup> group2D (new tcu::TestCaseGroup(testCtx, "2d", "2D Mipmap Filtering")); 1792 1793 de::MovePtr<tcu::TestCaseGroup> biasGroup2D (new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value")); 1794 de::MovePtr<tcu::TestCaseGroup> minLodGroup2D (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod")); 1795 de::MovePtr<tcu::TestCaseGroup> maxLodGroup2D (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod")); 1796 de::MovePtr<tcu::TestCaseGroup> baseLevelGroup2D (new tcu::TestCaseGroup(testCtx, "base_level", "Base level")); 1797 de::MovePtr<tcu::TestCaseGroup> maxLevelGroup2D (new tcu::TestCaseGroup(testCtx, "max_level", "Max level")); 1798 1799 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++) 1800 { 1801 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc)); 1802 1803 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1804 { 1805 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++) 1806 { 1807 // Add non_square variants to basic cases only. 1808 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex2DSizes) : 1; 1809 1810 for (int size = 0; size < sizeEnd; size++) 1811 { 1812 Texture2DMipmapTestCaseParameters testParameters; 1813 1814 testParameters.coordType = coordTypes[coordType].type; 1815 testParameters.minFilter = minFilterModes[minFilter].mode; 1816 testParameters.wrapS = wrapModes[wrapMode].mode; 1817 testParameters.wrapT = wrapModes[wrapMode].mode; 1818 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; //not sure (GL_RGBA) 1819 testParameters.width = tex2DSizes[size].width; 1820 testParameters.height = tex2DSizes[size].height; 1821 testParameters.programs.push_back(PROGRAM_2D_FLOAT); 1822 1823 std::ostringstream name; 1824 name << minFilterModes[minFilter].name 1825 << "_" << wrapModes[wrapMode].name; 1826 1827 if (tex2DSizes[size].name) 1828 name << "_" << tex2DSizes[size].name; 1829 1830 coordTypeGroup->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters)); 1831 } 1832 } 1833 } 1834 1835 group2D->addChild(coordTypeGroup.release()); 1836 } 1837 1838 // 2D bias variants. 1839 { 1840 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1841 { 1842 Texture2DMipmapTestCaseParameters testParameters; 1843 1844 testParameters.coordType = COORDTYPE_BASIC_BIAS; 1845 testParameters.minFilter = minFilterModes[minFilter].mode; 1846 testParameters.magFilter = minFilterModes[minFilter].mode; 1847 testParameters.wrapS = Sampler::REPEAT_GL; 1848 testParameters.wrapT = Sampler::REPEAT_GL; 1849 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; //not sure (GL_RGBA) 1850 testParameters.width = tex2DSizes[0].width; 1851 testParameters.height = tex2DSizes[0].height; 1852 testParameters.programs.push_back(PROGRAM_2D_FLOAT_BIAS); 1853 1854 std::ostringstream name; 1855 name << minFilterModes[minFilter].name; 1856 1857 biasGroup2D->addChild(new TextureTestCase<Texture2DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters)); 1858 } 1859 } 1860 1861 // 2D LOD controls. 1862 { 1863 // MIN_LOD 1864 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1865 { 1866 Texture2DMipmapTestCaseParameters testParameters; 1867 testParameters.minFilter = minFilterModes[minFilter].mode; 1868 testParameters.programs.push_back(PROGRAM_2D_FLOAT); 1869 1870 minLodGroup2D->addChild(new TextureTestCase<Texture2DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1871 } 1872 1873 // MAX_LOD 1874 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1875 { 1876 Texture2DMipmapTestCaseParameters testParameters; 1877 testParameters.minFilter = minFilterModes[minFilter].mode; 1878 testParameters.programs.push_back(PROGRAM_2D_FLOAT); 1879 1880 maxLodGroup2D->addChild(new TextureTestCase<Texture2DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1881 } 1882 } 1883 1884 { 1885 // BASE_LEVEL 1886 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1887 { 1888 Texture2DMipmapTestCaseParameters testParameters; 1889 testParameters.minFilter = minFilterModes[minFilter].mode; 1890 testParameters.minFilterName = minFilterModes[minFilter].name; 1891 testParameters.programs.push_back(PROGRAM_2D_FLOAT); 1892 1893 baseLevelGroup2D->addChild(new TextureTestCase<Texture2DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1894 } 1895 1896 // MAX_LEVEL 1897 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1898 { 1899 Texture2DMipmapTestCaseParameters testParameters; 1900 testParameters.minFilter = minFilterModes[minFilter].mode; 1901 testParameters.minFilterName = minFilterModes[minFilter].name; 1902 testParameters.programs.push_back(PROGRAM_2D_FLOAT); 1903 1904 maxLevelGroup2D->addChild(new TextureTestCase<Texture2DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1905 } 1906 } 1907 1908 group2D->addChild(biasGroup2D.release()); 1909 group2D->addChild(minLodGroup2D.release()); 1910 group2D->addChild(maxLodGroup2D.release()); 1911 group2D->addChild(baseLevelGroup2D.release()); 1912 group2D->addChild(maxLevelGroup2D.release()); 1913 1914 textureMipmappingTests->addChild(group2D.release()); 1915 } 1916 1917 // Cubemap cases. 1918 { 1919 de::MovePtr<tcu::TestCaseGroup> groupCube (new tcu::TestCaseGroup(testCtx, "cubemap", "Cube Mipmap Filtering")); 1920 1921 de::MovePtr<tcu::TestCaseGroup> minLodGroupCube (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod")); 1922 de::MovePtr<tcu::TestCaseGroup> maxLodGroupCube (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod")); 1923 de::MovePtr<tcu::TestCaseGroup> baseLevelGroupCube (new tcu::TestCaseGroup(testCtx, "base_level", "Base level")); 1924 de::MovePtr<tcu::TestCaseGroup> maxLevelGroupCube (new tcu::TestCaseGroup(testCtx, "max_level", "Max level")); 1925 1926 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(cubeCoordTypes); coordType++) 1927 { 1928 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, cubeCoordTypes[coordType].name, cubeCoordTypes[coordType].desc)); 1929 1930 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1931 { 1932 for (int magFilter = 0; magFilter < DE_LENGTH_OF_ARRAY(magFilterModes); magFilter++) 1933 { 1934 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++) 1935 { 1936 TextureCubeMipmapTestCaseParameters testParameters; 1937 1938 testParameters.coordType = cubeCoordTypes[coordType].type; 1939 testParameters.minFilter = minFilterModes[minFilter].mode; 1940 testParameters.magFilter = magFilterModes[magFilter].mode; 1941 testParameters.minFilterName = minFilterModes[minFilter].name; 1942 testParameters.wrapS = wrapModes[wrapMode].mode; 1943 testParameters.wrapT = wrapModes[wrapMode].mode; 1944 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; 1945 testParameters.size = cubeMapSize; 1946 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT); 1947 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT_BIAS); 1948 1949 std::ostringstream name; 1950 name << minFilterModes[minFilter].name 1951 << "_" << magFilterModes[magFilter].name 1952 << "_" << wrapModes[wrapMode].name; 1953 1954 coordTypeGroup->addChild(new TextureTestCase<TextureCubeMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters)); 1955 } 1956 } 1957 } 1958 1959 groupCube->addChild(coordTypeGroup.release()); 1960 } 1961 1962 // Cubemap LOD controls. 1963 { 1964 // MIN_LOD 1965 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1966 { 1967 TextureCubeMipmapTestCaseParameters testParameters; 1968 testParameters.minFilter = minFilterModes[minFilter].mode; 1969 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT); 1970 1971 minLodGroupCube->addChild(new TextureTestCase<TextureCubeMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1972 } 1973 1974 // MAX_LOD 1975 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1976 { 1977 TextureCubeMipmapTestCaseParameters testParameters; 1978 testParameters.minFilter = minFilterModes[minFilter].mode; 1979 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT); 1980 1981 maxLodGroupCube->addChild(new TextureTestCase<TextureCubeMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1982 } 1983 } 1984 1985 { 1986 // BASE_LEVEL 1987 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1988 { 1989 TextureCubeMipmapTestCaseParameters testParameters; 1990 testParameters.minFilter = minFilterModes[minFilter].mode; 1991 testParameters.minFilterName = minFilterModes[minFilter].name; 1992 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT); 1993 1994 baseLevelGroupCube->addChild(new TextureTestCase<TextureCubeBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 1995 } 1996 1997 // MAX_LEVEL 1998 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 1999 { 2000 TextureCubeMipmapTestCaseParameters testParameters; 2001 testParameters.minFilter = minFilterModes[minFilter].mode; 2002 testParameters.minFilterName = minFilterModes[minFilter].name; 2003 testParameters.programs.push_back(PROGRAM_CUBE_FLOAT); 2004 2005 maxLevelGroupCube->addChild(new TextureTestCase<TextureCubeMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 2006 } 2007 } 2008 2009 groupCube->addChild(minLodGroupCube.release()); 2010 groupCube->addChild(maxLodGroupCube.release()); 2011 groupCube->addChild(baseLevelGroupCube.release()); 2012 groupCube->addChild(maxLevelGroupCube.release()); 2013 2014 textureMipmappingTests->addChild(groupCube.release()); 2015 } 2016 2017 // 3D cases. 2018 { 2019 de::MovePtr<tcu::TestCaseGroup> group3D (new tcu::TestCaseGroup(testCtx, "3d", "3D Mipmap Filtering")); 2020 2021 de::MovePtr<tcu::TestCaseGroup> biasGroup3D (new tcu::TestCaseGroup(testCtx, "bias", "User-supplied bias value")); 2022 de::MovePtr<tcu::TestCaseGroup> minLodGroup3D (new tcu::TestCaseGroup(testCtx, "min_lod", "Lod control: min lod")); 2023 de::MovePtr<tcu::TestCaseGroup> maxLodGroup3D (new tcu::TestCaseGroup(testCtx, "max_lod", "Lod control: max lod")); 2024 de::MovePtr<tcu::TestCaseGroup> baseLevelGroup3D (new tcu::TestCaseGroup(testCtx, "base_level", "Base level")); 2025 de::MovePtr<tcu::TestCaseGroup> maxLevelGroup3D (new tcu::TestCaseGroup(testCtx, "max_level", "Max level")); 2026 2027 for (int coordType = 0; coordType < DE_LENGTH_OF_ARRAY(coordTypes); coordType++) 2028 { 2029 de::MovePtr<tcu::TestCaseGroup> coordTypeGroup (new tcu::TestCaseGroup(testCtx, coordTypes[coordType].name, coordTypes[coordType].desc)); 2030 2031 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 2032 { 2033 for (int wrapMode = 0; wrapMode < DE_LENGTH_OF_ARRAY(wrapModes); wrapMode++) 2034 { 2035 // Add other size variants to basic cases only. 2036 int sizeEnd = coordTypes[coordType].type == COORDTYPE_BASIC ? DE_LENGTH_OF_ARRAY(tex3DSizes) : 1; 2037 2038 Texture3DMipmapTestCaseParameters testParameters; 2039 2040 testParameters.coordType = coordTypes[coordType].type; 2041 testParameters.minFilter = minFilterModes[minFilter].mode; 2042 testParameters.minFilterName = minFilterModes[minFilter].name; 2043 testParameters.wrapR = wrapModes[wrapMode].mode; 2044 testParameters.wrapS = wrapModes[wrapMode].mode; 2045 testParameters.wrapT = wrapModes[wrapMode].mode; 2046 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; 2047 testParameters.programs.push_back(PROGRAM_3D_FLOAT); 2048 2049 for (int size = 0; size < sizeEnd; size++) 2050 { 2051 testParameters.width = tex3DSizes[size].width; 2052 testParameters.height = tex3DSizes[size].height; 2053 testParameters.depth = tex3DSizes[size].depth; 2054 2055 std::ostringstream name; 2056 name << minFilterModes[minFilter].name 2057 << "_" << wrapModes[wrapMode].name; 2058 2059 if (tex3DSizes[size].name) 2060 name << "_" << tex3DSizes[size].name; 2061 2062 coordTypeGroup->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, name.str().c_str(), "", testParameters)); 2063 } 2064 } 2065 } 2066 2067 group3D->addChild(coordTypeGroup.release()); 2068 } 2069 2070 // 3D bias variants. 2071 { 2072 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 2073 { 2074 Texture3DMipmapTestCaseParameters testParameters; 2075 testParameters.coordType = COORDTYPE_BASIC_BIAS; 2076 testParameters.minFilter = minFilterModes[minFilter].mode; 2077 testParameters.wrapR = Sampler::REPEAT_GL; 2078 testParameters.wrapS = Sampler::REPEAT_GL; 2079 testParameters.wrapT = Sampler::REPEAT_GL; 2080 testParameters.format = VK_FORMAT_R8G8B8A8_UNORM; 2081 testParameters.width = tex3DSizes[0].width; 2082 testParameters.height = tex3DSizes[0].height; 2083 testParameters.depth = tex3DSizes[0].depth; 2084 2085 testParameters.programs.push_back(PROGRAM_3D_FLOAT); 2086 testParameters.programs.push_back(PROGRAM_3D_FLOAT_BIAS); 2087 2088 biasGroup3D->addChild(new TextureTestCase<Texture3DMipmapTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 2089 } 2090 } 2091 2092 // 3D LOD controls. 2093 { 2094 // MIN_LOD 2095 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 2096 { 2097 Texture3DMipmapTestCaseParameters testParameters; 2098 testParameters.minFilter = minFilterModes[minFilter].mode; 2099 testParameters.programs.push_back(PROGRAM_3D_FLOAT); 2100 2101 minLodGroup3D->addChild(new TextureTestCase<Texture3DMinLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 2102 } 2103 2104 // MAX_LOD 2105 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 2106 { 2107 Texture3DMipmapTestCaseParameters testParameters; 2108 testParameters.minFilter = minFilterModes[minFilter].mode; 2109 testParameters.programs.push_back(PROGRAM_3D_FLOAT); 2110 2111 maxLodGroup3D->addChild(new TextureTestCase<Texture3DMaxLodTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 2112 } 2113 } 2114 2115 { 2116 // BASE_LEVEL 2117 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 2118 { 2119 Texture3DMipmapTestCaseParameters testParameters; 2120 testParameters.minFilter = minFilterModes[minFilter].mode; 2121 testParameters.minFilterName = minFilterModes[minFilter].name; 2122 testParameters.programs.push_back(PROGRAM_3D_FLOAT); 2123 2124 baseLevelGroup3D->addChild(new TextureTestCase<Texture3DBaseLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 2125 } 2126 2127 // MAX_LEVEL 2128 for (int minFilter = 0; minFilter < DE_LENGTH_OF_ARRAY(minFilterModes); minFilter++) 2129 { 2130 Texture3DMipmapTestCaseParameters testParameters; 2131 testParameters.minFilter = minFilterModes[minFilter].mode; 2132 testParameters.minFilterName = minFilterModes[minFilter].name; 2133 testParameters.programs.push_back(PROGRAM_3D_FLOAT); 2134 2135 maxLevelGroup3D->addChild(new TextureTestCase<Texture3DMaxLevelTestInstance>(testCtx, minFilterModes[minFilter].name, "", testParameters)); 2136 } 2137 } 2138 2139 group3D->addChild(biasGroup3D.release()); 2140 group3D->addChild(minLodGroup3D.release()); 2141 group3D->addChild(maxLodGroup3D.release()); 2142 group3D->addChild(baseLevelGroup3D.release()); 2143 group3D->addChild(maxLevelGroup3D.release()); 2144 2145 textureMipmappingTests->addChild(group3D.release()); 2146 } 2147} 2148 2149} // anonymous 2150 2151tcu::TestCaseGroup* createTextureMipmappingTests (tcu::TestContext& testCtx) 2152{ 2153 return createTestGroup(testCtx, "mipmap", "Texture mipmapping tests.", populateTextureMipmappingTests); 2154} 2155 2156} // texture 2157} // vkt 2158