1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2016 Samsung Electronics Co., Ltd. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Vulkan Image Clearing Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktApiImageClearingTests.hpp" 26 27 #include "deRandom.hpp" 28 #include "deMath.h" 29 #include "deSTLUtil.hpp" 30 #include "deStringUtil.hpp" 31 #include "deUniquePtr.hpp" 32 #include "deArrayUtil.hpp" 33 #include "deInt32.h" 34 #include "vkImageUtil.hpp" 35 #include "vkMemUtil.hpp" 36 #include "vktTestCase.hpp" 37 #include "vktTestCaseUtil.hpp" 38 #include "vktTestGroupUtil.hpp" 39 #include "vkQueryUtil.hpp" 40 #include "vkRefUtil.hpp" 41 #include "vkTypeUtil.hpp" 42 #include "tcuImageCompare.hpp" 43 #include "tcuTexture.hpp" 44 #include "tcuTextureUtil.hpp" 45 #include "tcuVectorType.hpp" 46 #include "tcuTexture.hpp" 47 #include "tcuFloat.hpp" 48 #include "tcuTestLog.hpp" 49 #include "tcuVectorUtil.hpp" 50 #include <sstream> 51 #include <numeric> 52 53 namespace vkt 54 { 55 56 namespace api 57 { 58 59 using namespace vk; 60 using namespace tcu; 61 62 namespace 63 { 64 65 enum AllocationKind 66 { 67 ALLOCATION_KIND_SUBALLOCATED, 68 ALLOCATION_KIND_DEDICATED, 69 }; 70 71 72 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki, 73 const DeviceInterface& vkd, 74 const VkPhysicalDevice& physDevice, 75 const VkDevice device, 76 const VkBuffer& buffer, 77 const MemoryRequirement requirement, 78 Allocator& allocator, 79 AllocationKind allocationKind) 80 { 81 switch (allocationKind) 82 { 83 case ALLOCATION_KIND_SUBALLOCATED: 84 { 85 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer); 86 87 return allocator.allocate(memoryRequirements, requirement); 88 } 89 90 case ALLOCATION_KIND_DEDICATED: 91 { 92 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement); 93 } 94 95 default: 96 { 97 TCU_THROW(InternalError, "Invalid allocation kind"); 98 } 99 } 100 } 101 102 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki, 103 const DeviceInterface& vkd, 104 const VkPhysicalDevice& physDevice, 105 const VkDevice device, 106 const VkImage& image, 107 const MemoryRequirement requirement, 108 Allocator& allocator, 109 AllocationKind allocationKind) 110 { 111 switch (allocationKind) 112 { 113 case ALLOCATION_KIND_SUBALLOCATED: 114 { 115 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image); 116 117 return allocator.allocate(memoryRequirements, requirement); 118 } 119 120 case ALLOCATION_KIND_DEDICATED: 121 { 122 return allocateDedicated(vki, vkd, physDevice, device, image, requirement); 123 } 124 125 default: 126 { 127 TCU_THROW(InternalError, "Invalid allocation kind"); 128 } 129 } 130 } 131 132 VkExtent3D getMipLevelExtent (VkExtent3D baseExtent, const deUint32 mipLevel) 133 { 134 baseExtent.width = std::max(baseExtent.width >> mipLevel, 1u); 135 baseExtent.height = std::max(baseExtent.height >> mipLevel, 1u); 136 baseExtent.depth = std::max(baseExtent.depth >> mipLevel, 1u); 137 return baseExtent; 138 } 139 140 deUint32 getNumMipLevels (const VkExtent3D& baseExtent, const deUint32 maxMipLevels) 141 { 142 const deUint32 widestEdge = std::max(std::max(baseExtent.width, baseExtent.height), baseExtent.depth); 143 return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, maxMipLevels); 144 } 145 146 deUint32 greatestCommonDivisor (const deUint32 a, const deUint32 b) 147 { 148 /* Find GCD */ 149 deUint32 temp; 150 deUint32 x=a; 151 deUint32 y=b; 152 153 while (x%y != 0) 154 { 155 temp = y; 156 y = x%y; 157 x = temp; 158 } 159 return y; 160 } 161 162 deUint32 lowestCommonMultiple (const deUint32 a, const deUint32 b) 163 { 164 return (a*b)/greatestCommonDivisor(a,b); 165 } 166 167 std::vector<deUint32> getImageMipLevelSizes (const deUint32 pixelSize, const VkExtent3D& baseExtent, const deUint32 numMipLevels, const deUint32 perLevelAlignment = 1u) 168 { 169 std::vector<deUint32> results(numMipLevels); 170 171 for (deUint32 mipLevel = 0; mipLevel < numMipLevels; ++mipLevel) 172 { 173 const VkExtent3D extent = getMipLevelExtent(baseExtent, mipLevel); 174 results[mipLevel] = static_cast<deUint32>(extent.width * extent.height * extent.depth * pixelSize); 175 results[mipLevel] = ((results[mipLevel] + perLevelAlignment-1) / perLevelAlignment) * perLevelAlignment; 176 } 177 178 return results; 179 } 180 181 struct LayerRange 182 { 183 deUint32 baseArrayLayer; 184 deUint32 layerCount; 185 }; 186 187 inline bool isInClearRange (const UVec4& clearCoords, const deUint32 x, const deUint32 y, deUint32 arrayLayer = 0, tcu::Maybe<LayerRange> imageViewLayerRange = tcu::Maybe<LayerRange>(), tcu::Maybe<LayerRange> attachmentClearLayerRange = tcu::Maybe<LayerRange>()) 188 { 189 if (attachmentClearLayerRange) 190 { 191 // Only layers in range passed to clear command are cleared 192 193 const deUint32 clearBaseLayer = (imageViewLayerRange ? imageViewLayerRange->baseArrayLayer : 0) + attachmentClearLayerRange->baseArrayLayer; 194 195 if ((arrayLayer < clearBaseLayer) || (arrayLayer >= (clearBaseLayer + attachmentClearLayerRange->layerCount))) 196 { 197 return false; 198 } 199 } 200 201 if (clearCoords == UVec4()) 202 { 203 return true; 204 } 205 206 //! Check if a point lies in a cross-like area. 207 return !((x < clearCoords[0] && y < clearCoords[1]) || 208 (x < clearCoords[0] && y >= clearCoords[3]) || 209 (x >= clearCoords[2] && y < clearCoords[1]) || 210 (x >= clearCoords[2] && y >= clearCoords[3])); 211 } 212 213 inline bool isInInitialClearRange (bool isAttachmentformat, deUint32 mipLevel, deUint32 arrayLayer, LayerRange imageViewLayerRange) 214 { 215 if (!isAttachmentformat) 216 { 217 // initial clear is done using renderpass load op - does not apply for non-renderable formats 218 return false; 219 } 220 221 if (mipLevel > 0) 222 { 223 // intial clear is done using FB bound to level 0 only 224 return false; 225 } 226 227 // Only layers in range bound to framebuffer are cleared to initial color 228 if ((arrayLayer < imageViewLayerRange.baseArrayLayer) || (arrayLayer >= (imageViewLayerRange.baseArrayLayer + imageViewLayerRange.layerCount))) 229 { 230 return false; 231 } 232 233 return true; 234 } 235 236 // This method is copied from the vktRenderPassTests.cpp. It should be moved to a common place. 237 int calcFloatDiff (float a, float b) 238 { 239 const int asign = Float32(a).sign(); 240 const int bsign = Float32(a).sign(); 241 242 const deUint32 avalue = (Float32(a).bits() & ((0x1u << 31u) - 1u)); 243 const deUint32 bvalue = (Float32(b).bits() & ((0x1u << 31u) - 1u)); 244 245 if (asign != bsign) 246 return avalue + bvalue + 1u; 247 else if (avalue < bvalue) 248 return bvalue - avalue; 249 else 250 return avalue - bvalue; 251 } 252 253 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter. 254 bool comparePixelToDepthClearValue (const ConstPixelBufferAccess& access, 255 int x, 256 int y, 257 float ref, 258 std::string& stringResult) 259 { 260 const TextureFormat format = getEffectiveDepthStencilTextureFormat(access.getFormat(), Sampler::MODE_DEPTH); 261 const TextureChannelClass channelClass = getTextureChannelClass(format.type); 262 263 switch (channelClass) 264 { 265 case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 266 case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 267 { 268 const int bitDepth = getTextureFormatBitDepth(format).x(); 269 const float depth = access.getPixDepth(x, y); 270 const float threshold = 2.0f / (float)((1 << bitDepth) - 1); 271 const bool result = deFloatAbs(depth - ref) <= threshold; 272 273 if (!result) 274 { 275 std::stringstream s; 276 s << "Ref:" << ref << " Threshold:" << threshold << " Depth:" << depth; 277 stringResult = s.str(); 278 } 279 280 return result; 281 } 282 283 case TEXTURECHANNELCLASS_FLOATING_POINT: 284 { 285 const float depth = access.getPixDepth(x, y); 286 const int mantissaBits = getTextureFormatMantissaBitDepth(format).x(); 287 const int threshold = 10 * 1 << (23 - mantissaBits); 288 289 DE_ASSERT(mantissaBits <= 23); 290 291 const bool result = calcFloatDiff(depth, ref) <= threshold; 292 293 if (!result) 294 { 295 float floatThreshold = Float32((deUint32)threshold).asFloat(); 296 std::stringstream s; 297 298 s << "Ref:" << ref << " Threshold:" << floatThreshold << " Depth:" << depth; 299 stringResult = s.str(); 300 } 301 302 return result; 303 } 304 305 default: 306 DE_FATAL("Invalid channel class"); 307 return false; 308 } 309 } 310 311 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter. 312 bool comparePixelToStencilClearValue (const ConstPixelBufferAccess& access, 313 int x, 314 int y, 315 deUint32 ref, 316 std::string& stringResult) 317 { 318 const deUint32 stencil = access.getPixStencil(x, y); 319 const bool result = stencil == ref; 320 321 if (!result) 322 { 323 std::stringstream s; 324 s << "Ref:" << ref << " Threshold:0" << " Stencil:" << stencil; 325 stringResult = s.str(); 326 } 327 328 return result; 329 } 330 331 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter. 332 bool comparePixelToColorClearValue (const ConstPixelBufferAccess& access, 333 int x, 334 int y, 335 int z, 336 const VkClearColorValue& ref, 337 std::string& stringResult) 338 { 339 const TextureFormat format = access.getFormat(); 340 const TextureChannelClass channelClass = getTextureChannelClass(format.type); 341 const BVec4 channelMask = getTextureFormatChannelMask(format); 342 343 switch (channelClass) 344 { 345 case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 346 case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 347 { 348 const IVec4 bitDepth (getTextureFormatBitDepth(format)); 349 const Vec4 resColor (access.getPixel(x, y, z)); 350 Vec4 refColor (ref.float32[0], 351 ref.float32[1], 352 ref.float32[2], 353 ref.float32[3]); 354 const int modifier = (channelClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) ? 0 : 1; 355 const Vec4 threshold (bitDepth[0] > 0 ? 1.0f / ((float)(1 << (bitDepth[0] - modifier)) - 1.0f) : 1.0f, 356 bitDepth[1] > 0 ? 1.0f / ((float)(1 << (bitDepth[1] - modifier)) - 1.0f) : 1.0f, 357 bitDepth[2] > 0 ? 1.0f / ((float)(1 << (bitDepth[2] - modifier)) - 1.0f) : 1.0f, 358 bitDepth[3] > 0 ? 1.0f / ((float)(1 << (bitDepth[3] - modifier)) - 1.0f) : 1.0f); 359 360 if (isSRGB(access.getFormat())) 361 refColor = linearToSRGB(refColor); 362 363 const bool result = !(anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold), channelMask), channelMask)); 364 365 if (!result) 366 { 367 std::stringstream s; 368 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold << " Color:" << resColor; 369 stringResult = s.str(); 370 } 371 372 return result; 373 } 374 375 case TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 376 { 377 const UVec4 resColor (access.getPixelUint(x, y, z)); 378 const UVec4 refColor (ref.uint32[0], 379 ref.uint32[1], 380 ref.uint32[2], 381 ref.uint32[3]); 382 const UVec4 threshold (1); 383 384 const bool result = !(anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold), channelMask), channelMask)); 385 386 if (!result) 387 { 388 std::stringstream s; 389 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold << " Color:" << resColor; 390 stringResult = s.str(); 391 } 392 393 return result; 394 } 395 396 case TEXTURECHANNELCLASS_SIGNED_INTEGER: 397 { 398 const IVec4 resColor (access.getPixelInt(x, y, z)); 399 const IVec4 refColor (ref.int32[0], 400 ref.int32[1], 401 ref.int32[2], 402 ref.int32[3]); 403 const IVec4 threshold (1); 404 405 const bool result = !(anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold), channelMask), channelMask)); 406 407 if (!result) 408 { 409 std::stringstream s; 410 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold << " Color:" << resColor; 411 stringResult = s.str(); 412 } 413 414 return result; 415 } 416 417 case TEXTURECHANNELCLASS_FLOATING_POINT: 418 { 419 const Vec4 resColor (access.getPixel(x, y, z)); 420 const Vec4 refColor (ref.float32[0], 421 ref.float32[1], 422 ref.float32[2], 423 ref.float32[3]); 424 const IVec4 mantissaBits (getTextureFormatMantissaBitDepth(format)); 425 const IVec4 threshold (10 * IVec4(1) << (23 - mantissaBits)); 426 427 DE_ASSERT(allEqual(greaterThanEqual(threshold, IVec4(0)), BVec4(true))); 428 429 for (int ndx = 0; ndx < 4; ndx++) 430 { 431 const bool result = !(calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold[ndx] && channelMask[ndx]); 432 433 if (!result) 434 { 435 float floatThreshold = Float32((deUint32)(threshold)[0]).asFloat(); 436 Vec4 thresholdVec4 (floatThreshold, 437 floatThreshold, 438 floatThreshold, 439 floatThreshold); 440 std::stringstream s; 441 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << thresholdVec4 << " Color:" << resColor; 442 stringResult = s.str(); 443 444 return false; 445 } 446 } 447 448 return true; 449 } 450 451 default: 452 DE_FATAL("Invalid channel class"); 453 return false; 454 } 455 } 456 457 struct TestParams 458 { 459 bool useSingleMipLevel; //!< only mip level 0, otherwise up to maxMipLevels 460 VkImageType imageType; 461 VkFormat imageFormat; 462 VkExtent3D imageExtent; 463 deUint32 imageLayerCount; 464 LayerRange imageViewLayerRange; 465 VkClearValue initValue; 466 VkClearValue clearValue[2]; //!< the second value is used with more than one mip map 467 LayerRange clearLayerRange; 468 AllocationKind allocationKind; 469 }; 470 471 class ImageClearingTestInstance : public vkt::TestInstance 472 { 473 public: 474 ImageClearingTestInstance (Context& context, 475 const TestParams& testParams); 476 477 Move<VkCommandPool> createCommandPool (VkCommandPoolCreateFlags commandPoolCreateFlags) const; 478 Move<VkCommandBuffer> allocatePrimaryCommandBuffer (VkCommandPool commandPool) const; 479 Move<VkImage> createImage (VkImageType imageType, VkFormat format, VkExtent3D extent, deUint32 arrayLayerCount, VkImageUsageFlags usage) const; 480 Move<VkImageView> createImageView (VkImage image, VkImageViewType viewType, VkFormat format, VkImageAspectFlags aspectMask, LayerRange layerRange) const; 481 Move<VkRenderPass> createRenderPass (VkFormat format) const; 482 Move<VkFramebuffer> createFrameBuffer (VkImageView imageView, VkRenderPass renderPass, deUint32 imageWidth, deUint32 imageHeight, deUint32 imageLayersCount) const; 483 484 void beginCommandBuffer (VkCommandBufferUsageFlags usageFlags) const; 485 void endCommandBuffer (void) const; 486 void submitCommandBuffer (void) const; 487 void beginRenderPass (VkSubpassContents content, VkClearValue clearValue) const; 488 489 void pipelineImageBarrier (VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const; 490 de::MovePtr<TextureLevelPyramid> readImage (VkImageAspectFlags aspectMask, deUint32 baseLayer) const; 491 tcu::TestStatus verifyResultImage (const std::string& successMessage, const UVec4& clearCoords = UVec4()) const; 492 493 protected: 494 enum ViewType 495 { 496 VIEW_TYPE_SINGLE, 497 VIEW_TYPE_ARRAY 498 }; 499 VkImageViewType getCorrespondingImageViewType (VkImageType imageType, ViewType viewType) const; 500 VkImageUsageFlags getImageUsageFlags (VkFormat format) const; 501 VkImageAspectFlags getImageAspectFlags (VkFormat format) const; 502 bool getIsAttachmentFormat (VkFormat format) const; 503 bool getIsStencilFormat (VkFormat format) const; 504 bool getIsDepthFormat (VkFormat format) const; 505 VkImageFormatProperties getImageFormatProperties (void) const; 506 de::MovePtr<Allocation> allocateAndBindImageMemory (VkImage image) const; 507 508 const TestParams& m_params; 509 const VkDevice m_device; 510 const InstanceInterface& m_vki; 511 const DeviceInterface& m_vkd; 512 const VkQueue m_queue; 513 const deUint32 m_queueFamilyIndex; 514 Allocator& m_allocator; 515 516 const bool m_isAttachmentFormat; 517 const VkImageUsageFlags m_imageUsageFlags; 518 const VkImageAspectFlags m_imageAspectFlags; 519 const VkImageFormatProperties m_imageFormatProperties; 520 const deUint32 m_imageMipLevels; 521 const deUint32 m_thresholdMipLevel; 522 523 Unique<VkCommandPool> m_commandPool; 524 Unique<VkCommandBuffer> m_commandBuffer; 525 526 Unique<VkImage> m_image; 527 de::MovePtr<Allocation> m_imageMemory; 528 Unique<VkImageView> m_imageView; 529 Unique<VkRenderPass> m_renderPass; 530 Unique<VkFramebuffer> m_frameBuffer; 531 }; 532 533 ImageClearingTestInstance::ImageClearingTestInstance (Context& context, const TestParams& params) 534 : TestInstance (context) 535 , m_params (params) 536 , m_device (context.getDevice()) 537 , m_vki (context.getInstanceInterface()) 538 , m_vkd (context.getDeviceInterface()) 539 , m_queue (context.getUniversalQueue()) 540 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex()) 541 , m_allocator (context.getDefaultAllocator()) 542 , m_isAttachmentFormat (getIsAttachmentFormat(params.imageFormat)) 543 , m_imageUsageFlags (getImageUsageFlags(params.imageFormat)) 544 , m_imageAspectFlags (getImageAspectFlags(params.imageFormat)) 545 , m_imageFormatProperties (getImageFormatProperties()) 546 , m_imageMipLevels (params.useSingleMipLevel ? 1u : getNumMipLevels(params.imageExtent, m_imageFormatProperties.maxMipLevels)) 547 , m_thresholdMipLevel (std::max(m_imageMipLevels / 2u, 1u)) 548 , m_commandPool (createCommandPool(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)) 549 , m_commandBuffer (allocatePrimaryCommandBuffer(*m_commandPool)) 550 551 , m_image (createImage(params.imageType, 552 params.imageFormat, 553 params.imageExtent, 554 params.imageLayerCount, 555 m_imageUsageFlags)) 556 557 , m_imageMemory (allocateAndBindImageMemory(*m_image)) 558 , m_imageView (m_isAttachmentFormat ? createImageView(*m_image, 559 getCorrespondingImageViewType(params.imageType, params.imageLayerCount > 1u ? VIEW_TYPE_ARRAY : VIEW_TYPE_SINGLE), 560 params.imageFormat, 561 m_imageAspectFlags, 562 params.imageViewLayerRange) : vk::Move<VkImageView>()) 563 564 , m_renderPass (m_isAttachmentFormat ? createRenderPass(params.imageFormat) : vk::Move<vk::VkRenderPass>()) 565 , m_frameBuffer (m_isAttachmentFormat ? createFrameBuffer(*m_imageView, *m_renderPass, params.imageExtent.width, params.imageExtent.height, params.imageViewLayerRange.layerCount) : vk::Move<vk::VkFramebuffer>()) 566 { 567 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED) 568 { 569 const std::string extensionName("VK_KHR_dedicated_allocation"); 570 571 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName)) 572 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); 573 } 574 } 575 576 VkImageViewType ImageClearingTestInstance::getCorrespondingImageViewType (VkImageType imageType, ViewType viewType) const 577 { 578 switch (imageType) 579 { 580 case VK_IMAGE_TYPE_1D: 581 return (viewType == VIEW_TYPE_ARRAY) ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D; 582 case VK_IMAGE_TYPE_2D: 583 return (viewType == VIEW_TYPE_ARRAY) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; 584 case VK_IMAGE_TYPE_3D: 585 if (viewType != VIEW_TYPE_SINGLE) 586 { 587 DE_FATAL("Cannot have 3D image array"); 588 } 589 return VK_IMAGE_VIEW_TYPE_3D; 590 default: 591 DE_FATAL("Unknown image type!"); 592 } 593 594 return VK_IMAGE_VIEW_TYPE_2D; 595 } 596 597 VkImageUsageFlags ImageClearingTestInstance::getImageUsageFlags (VkFormat format) const 598 { 599 VkImageUsageFlags commonFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 600 601 if (m_isAttachmentFormat) 602 { 603 if (isDepthStencilFormat(format)) 604 return commonFlags | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; 605 606 return commonFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 607 } 608 return commonFlags; 609 } 610 611 VkImageAspectFlags ImageClearingTestInstance::getImageAspectFlags (VkFormat format) const 612 { 613 VkImageAspectFlags imageAspectFlags = 0; 614 615 if (getIsDepthFormat(format)) 616 imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT; 617 618 if (getIsStencilFormat(format)) 619 imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; 620 621 if (imageAspectFlags == 0) 622 imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; 623 624 return imageAspectFlags; 625 } 626 627 bool ImageClearingTestInstance::getIsAttachmentFormat (VkFormat format) const 628 { 629 const VkFormatProperties props = vk::getPhysicalDeviceFormatProperties(m_vki, m_context.getPhysicalDevice(), format); 630 631 return (props.optimalTilingFeatures & (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) != 0; 632 } 633 634 bool ImageClearingTestInstance::getIsStencilFormat (VkFormat format) const 635 { 636 const TextureFormat tcuFormat = mapVkFormat(format); 637 638 if (tcuFormat.order == TextureFormat::S || tcuFormat.order == TextureFormat::DS) 639 return true; 640 641 return false; 642 } 643 644 bool ImageClearingTestInstance::getIsDepthFormat (VkFormat format) const 645 { 646 const TextureFormat tcuFormat = mapVkFormat(format); 647 648 if (tcuFormat.order == TextureFormat::D || tcuFormat.order == TextureFormat::DS) 649 return true; 650 651 return false; 652 } 653 654 VkImageFormatProperties ImageClearingTestInstance::getImageFormatProperties (void) const 655 { 656 VkImageFormatProperties properties; 657 const VkResult result = m_vki.getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(), m_params.imageFormat, m_params.imageType, 658 VK_IMAGE_TILING_OPTIMAL, m_imageUsageFlags, (VkImageCreateFlags)0, &properties); 659 660 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) 661 TCU_THROW(NotSupportedError, "Format not supported"); 662 else 663 return properties; 664 } 665 666 de::MovePtr<Allocation> ImageClearingTestInstance::allocateAndBindImageMemory (VkImage image) const 667 { 668 de::MovePtr<Allocation> imageMemory (allocateImage(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, image, MemoryRequirement::Any, m_allocator, m_params.allocationKind)); 669 VK_CHECK(m_vkd.bindImageMemory(m_device, image, imageMemory->getMemory(), imageMemory->getOffset())); 670 return imageMemory; 671 } 672 673 Move<VkCommandPool> ImageClearingTestInstance::createCommandPool (VkCommandPoolCreateFlags commandPoolCreateFlags) const 674 { 675 return vk::createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex); 676 } 677 678 Move<VkCommandBuffer> ImageClearingTestInstance::allocatePrimaryCommandBuffer (VkCommandPool commandPool) const 679 { 680 return vk::allocateCommandBuffer(m_vkd, m_device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 681 } 682 683 Move<VkImage> ImageClearingTestInstance::createImage (VkImageType imageType, VkFormat format, VkExtent3D extent, deUint32 arrayLayerCount, VkImageUsageFlags usage) const 684 { 685 const VkImageCreateInfo imageCreateInfo = 686 { 687 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 688 DE_NULL, // const void* pNext; 689 0u, // VkImageCreateFlags flags; 690 imageType, // VkImageType imageType; 691 format, // VkFormat format; 692 extent, // VkExtent3D extent; 693 m_imageMipLevels, // deUint32 mipLevels; 694 arrayLayerCount, // deUint32 arrayLayers; 695 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 696 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 697 usage, // VkImageUsageFlags usage; 698 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 699 1u, // deUint32 queueFamilyIndexCount; 700 &m_queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 701 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 702 }; 703 704 return vk::createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL); 705 } 706 707 Move<VkImageView> ImageClearingTestInstance::createImageView (VkImage image, VkImageViewType viewType, VkFormat format, VkImageAspectFlags aspectMask, LayerRange layerRange) const 708 { 709 const VkImageViewCreateInfo imageViewCreateInfo = 710 { 711 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 712 DE_NULL, // const void* pNext; 713 0u, // VkImageViewCreateFlags flags; 714 image, // VkImage image; 715 viewType, // VkImageViewType viewType; 716 format, // VkFormat format; 717 { 718 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle r; 719 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle g; 720 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle b; 721 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle a; 722 }, // VkComponentMapping components; 723 { 724 aspectMask, // VkImageAspectFlags aspectMask; 725 0u, // deUint32 baseMipLevel; 726 1u, // deUint32 mipLevels; 727 layerRange.baseArrayLayer, // deUint32 baseArrayLayer; 728 layerRange.layerCount, // deUint32 arraySize; 729 }, // VkImageSubresourceRange subresourceRange; 730 }; 731 732 return vk::createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL); 733 } 734 735 Move<VkRenderPass> ImageClearingTestInstance::createRenderPass (VkFormat format) const 736 { 737 VkImageLayout imageLayout; 738 739 if (isDepthStencilFormat(format)) 740 imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; 741 else 742 imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 743 744 const VkAttachmentDescription attachmentDesc = 745 { 746 0u, // VkAttachmentDescriptionFlags flags; 747 format, // VkFormat format; 748 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 749 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 750 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 751 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp; 752 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; 753 imageLayout, // VkImageLayout initialLayout; 754 imageLayout, // VkImageLayout finalLayout; 755 }; 756 757 const VkAttachmentDescription attachments[1] = 758 { 759 attachmentDesc 760 }; 761 762 const VkAttachmentReference attachmentRef = 763 { 764 0u, // deUint32 attachment; 765 imageLayout, // VkImageLayout layout; 766 }; 767 768 const VkAttachmentReference* pColorAttachments = DE_NULL; 769 const VkAttachmentReference* pDepthStencilAttachment = DE_NULL; 770 deUint32 colorAttachmentCount = 1; 771 772 if (isDepthStencilFormat(format)) 773 { 774 colorAttachmentCount = 0; 775 pDepthStencilAttachment = &attachmentRef; 776 } 777 else 778 { 779 colorAttachmentCount = 1; 780 pColorAttachments = &attachmentRef; 781 } 782 783 const VkSubpassDescription subpassDesc[1] = 784 { 785 { 786 0u, // VkSubpassDescriptionFlags flags; 787 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 788 0u, // deUint32 inputAttachmentCount; 789 DE_NULL, // const VkAttachmentReference* pInputAttachments; 790 colorAttachmentCount, // deUint32 colorAttachmentCount; 791 pColorAttachments, // const VkAttachmentReference* pColorAttachments; 792 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 793 pDepthStencilAttachment, // const VkAttachmentReference* pDepthStencilAttachment; 794 0u, // deUint32 preserveAttachmentCount; 795 DE_NULL, // const VkAttachmentReference* pPreserveAttachments; 796 } 797 }; 798 799 const VkRenderPassCreateInfo renderPassCreateInfo = 800 { 801 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 802 DE_NULL, // const void* pNext; 803 0u, // VkRenderPassCreateFlags flags; 804 1u, // deUint32 attachmentCount; 805 attachments, // const VkAttachmentDescription* pAttachments; 806 1u, // deUint32 subpassCount; 807 subpassDesc, // const VkSubpassDescription* pSubpasses; 808 0u, // deUint32 dependencyCount; 809 DE_NULL, // const VkSubpassDependency* pDependencies; 810 }; 811 812 return vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo, DE_NULL); 813 } 814 815 Move<VkFramebuffer> ImageClearingTestInstance::createFrameBuffer (VkImageView imageView, VkRenderPass renderPass, deUint32 imageWidth, deUint32 imageHeight, deUint32 imageLayersCount) const 816 { 817 const VkImageView attachmentViews[1] = 818 { 819 imageView 820 }; 821 822 const VkFramebufferCreateInfo framebufferCreateInfo = 823 { 824 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 825 DE_NULL, // const void* pNext; 826 0u, // VkFramebufferCreateFlags flags; 827 renderPass, // VkRenderPass renderPass; 828 1, // deUint32 attachmentCount; 829 attachmentViews, // const VkImageView* pAttachments; 830 imageWidth, // deUint32 width; 831 imageHeight, // deUint32 height; 832 imageLayersCount, // deUint32 layers; 833 }; 834 835 return createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL); 836 } 837 838 void ImageClearingTestInstance::beginCommandBuffer (VkCommandBufferUsageFlags usageFlags) const 839 { 840 const VkCommandBufferBeginInfo commandBufferBeginInfo = 841 { 842 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 843 DE_NULL, // const void* pNext; 844 usageFlags, // VkCommandBufferUsageFlags flags; 845 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 846 }; 847 848 VK_CHECK(m_vkd.beginCommandBuffer(*m_commandBuffer, &commandBufferBeginInfo)); 849 } 850 851 void ImageClearingTestInstance::endCommandBuffer (void) const 852 { 853 VK_CHECK(m_vkd.endCommandBuffer(*m_commandBuffer)); 854 } 855 856 void ImageClearingTestInstance::submitCommandBuffer (void) const 857 { 858 const Unique<VkFence> fence (createFence(m_vkd, m_device)); 859 860 const VkSubmitInfo submitInfo = 861 { 862 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 863 DE_NULL, // const void* pNext; 864 0u, // deUint32 waitSemaphoreCount; 865 DE_NULL, // const VkSemaphore* pWaitSemaphores; 866 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 867 1u, // deUint32 commandBufferCount; 868 &(*m_commandBuffer), // const VkCommandBuffer* pCommandBuffers; 869 0u, // deUint32 signalSemaphoreCount; 870 DE_NULL // const VkSemaphore* pSignalSemaphores; 871 }; 872 873 VK_CHECK(m_vkd.queueSubmit(m_queue, 1, &submitInfo, *fence)); 874 875 VK_CHECK(m_vkd.waitForFences(m_device, 1, &fence.get(), VK_TRUE, ~0ull)); 876 } 877 878 void ImageClearingTestInstance::pipelineImageBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const 879 { 880 const VkImageMemoryBarrier imageBarrier = 881 { 882 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 883 DE_NULL, // const void* pNext; 884 srcAccessMask, // VkAccessFlags srcAccessMask; 885 dstAccessMask, // VkAccessFlags dstAccessMask; 886 oldLayout, // VkImageLayout oldLayout; 887 newLayout, // VkImageLayout newLayout; 888 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 889 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 890 *m_image, // VkImage image; 891 { 892 m_imageAspectFlags, // VkImageAspectFlags aspectMask; 893 0u, // deUint32 baseMipLevel; 894 VK_REMAINING_MIP_LEVELS, // deUint32 levelCount; 895 0u, // deUint32 baseArrayLayer; 896 VK_REMAINING_ARRAY_LAYERS, // deUint32 layerCount; 897 }, // VkImageSubresourceRange subresourceRange; 898 }; 899 900 m_vkd.cmdPipelineBarrier(*m_commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier); 901 } 902 903 de::MovePtr<TextureLevelPyramid> ImageClearingTestInstance::readImage (VkImageAspectFlags aspectMask, deUint32 arrayLayer) const 904 { 905 const TextureFormat tcuFormat = aspectMask == VK_IMAGE_ASPECT_COLOR_BIT ? mapVkFormat(m_params.imageFormat) : 906 aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ? getDepthCopyFormat(m_params.imageFormat) : 907 aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT ? getStencilCopyFormat(m_params.imageFormat) : 908 TextureFormat(); 909 const deUint32 pixelSize = getPixelSize(tcuFormat); 910 deUint32 alignment = 4; // subsequent mip levels aligned to 4 bytes 911 912 if (!getIsDepthFormat(m_params.imageFormat) && !getIsStencilFormat(m_params.imageFormat)) 913 alignment = lowestCommonMultiple(pixelSize, alignment); // alignment must be multiple of pixel size, if not D/S. 914 915 const std::vector<deUint32> mipLevelSizes = getImageMipLevelSizes(pixelSize, m_params.imageExtent, m_imageMipLevels, alignment); 916 const VkDeviceSize imageTotalSize = std::accumulate(mipLevelSizes.begin(), mipLevelSizes.end(), 0u); 917 918 de::MovePtr<TextureLevelPyramid> result (new TextureLevelPyramid(tcuFormat, m_imageMipLevels)); 919 Move<VkBuffer> buffer; 920 de::MovePtr<Allocation> bufferAlloc; 921 922 // Create destination buffer 923 { 924 const VkBufferCreateInfo bufferParams = 925 { 926 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 927 DE_NULL, // const void* pNext; 928 0u, // VkBufferCreateFlags flags; 929 imageTotalSize, // VkDeviceSize size; 930 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 931 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 932 0u, // deUint32 queueFamilyIndexCount; 933 DE_NULL // const deUint32* pQueueFamilyIndices; 934 }; 935 936 buffer = createBuffer(m_vkd, m_device, &bufferParams); 937 bufferAlloc = allocateBuffer(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, *buffer, MemoryRequirement::HostVisible, m_allocator, m_params.allocationKind); 938 VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 939 } 940 941 // Barriers for copying image to buffer 942 943 const VkBufferMemoryBarrier bufferBarrier = 944 { 945 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 946 DE_NULL, // const void* pNext; 947 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 948 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 949 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 950 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 951 *buffer, // VkBuffer buffer; 952 0u, // VkDeviceSize offset; 953 imageTotalSize, // VkDeviceSize size; 954 }; 955 956 // Copy image to buffer 957 std::vector<VkBufferImageCopy> copyRegions; 958 { 959 deUint32 offset = 0u; 960 for (deUint32 mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel) 961 { 962 const VkExtent3D extent = getMipLevelExtent(m_params.imageExtent, mipLevel); 963 const VkBufferImageCopy region = 964 { 965 offset, // VkDeviceSize bufferOffset; 966 0u, // deUint32 bufferRowLength; 967 0u, // deUint32 bufferImageHeight; 968 { aspectMask, mipLevel, arrayLayer, 1u }, // VkImageSubresourceLayers imageSubresource; 969 { 0, 0, 0 }, // VkOffset3D imageOffset; 970 extent // VkExtent3D imageExtent; 971 }; 972 copyRegions.push_back(region); 973 offset += mipLevelSizes[mipLevel]; 974 } 975 } 976 977 beginCommandBuffer(0); 978 979 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, 980 VK_PIPELINE_STAGE_TRANSFER_BIT, 981 VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 982 VK_ACCESS_TRANSFER_READ_BIT, 983 VK_IMAGE_LAYOUT_GENERAL, 984 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 985 986 m_vkd.cmdCopyImageToBuffer(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, static_cast<deUint32>(copyRegions.size()), ©Regions[0]); 987 m_vkd.cmdPipelineBarrier(*m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 988 989 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, 990 VK_PIPELINE_STAGE_TRANSFER_BIT, 991 VK_ACCESS_TRANSFER_READ_BIT, 992 VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, 993 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 994 VK_IMAGE_LAYOUT_GENERAL); 995 996 endCommandBuffer(); 997 submitCommandBuffer(); 998 999 invalidateMappedMemoryRange(m_vkd, m_device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), imageTotalSize); 1000 1001 { 1002 deUint32 offset = 0u; 1003 for (deUint32 mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel) 1004 { 1005 const VkExtent3D extent = getMipLevelExtent(m_params.imageExtent, mipLevel); 1006 const void* pLevelData = static_cast<const void*>(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + offset); 1007 1008 result->allocLevel(mipLevel, extent.width, extent.height, extent.depth); 1009 copy(result->getLevel(mipLevel), ConstPixelBufferAccess(result->getFormat(), result->getLevel(mipLevel).getSize(), pLevelData)); 1010 1011 offset += mipLevelSizes[mipLevel]; 1012 } 1013 } 1014 1015 return result; 1016 } 1017 1018 tcu::TestStatus ImageClearingTestInstance::verifyResultImage (const std::string& successMessage, const UVec4& clearCoords) const 1019 { 1020 DE_ASSERT((clearCoords == UVec4()) || m_params.imageExtent.depth == 1u); 1021 1022 if (getIsDepthFormat(m_params.imageFormat)) 1023 { 1024 DE_ASSERT(m_imageMipLevels == 1u); 1025 1026 for (deUint32 arrayLayer = 0; arrayLayer < m_params.imageLayerCount; ++arrayLayer) 1027 { 1028 de::MovePtr<TextureLevelPyramid> image = readImage(VK_IMAGE_ASPECT_DEPTH_BIT, arrayLayer); 1029 std::string message; 1030 float depthValue; 1031 1032 for (deUint32 y = 0; y < m_params.imageExtent.height; ++y) 1033 for (deUint32 x = 0; x < m_params.imageExtent.width; ++x) 1034 { 1035 if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange, m_params.clearLayerRange)) 1036 depthValue = m_params.clearValue[0].depthStencil.depth; 1037 else 1038 if (isInInitialClearRange(m_isAttachmentFormat, 0u /* mipLevel */, arrayLayer, m_params.imageViewLayerRange)) 1039 { 1040 depthValue = m_params.initValue.depthStencil.depth; 1041 } 1042 else 1043 continue; 1044 1045 if (!comparePixelToDepthClearValue(image->getLevel(0), x, y, depthValue, message)) 1046 return TestStatus::fail("Depth value mismatch! " + message); 1047 } 1048 } 1049 } 1050 1051 if (getIsStencilFormat(m_params.imageFormat)) 1052 { 1053 DE_ASSERT(m_imageMipLevels == 1u); 1054 1055 for (deUint32 arrayLayer = 0; arrayLayer < m_params.imageLayerCount; ++arrayLayer) 1056 { 1057 de::MovePtr<TextureLevelPyramid> image = readImage(VK_IMAGE_ASPECT_STENCIL_BIT, arrayLayer); 1058 std::string message; 1059 deUint32 stencilValue; 1060 1061 for (deUint32 y = 0; y < m_params.imageExtent.height; ++y) 1062 for (deUint32 x = 0; x < m_params.imageExtent.width; ++x) 1063 { 1064 if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange, m_params.clearLayerRange)) 1065 stencilValue = m_params.clearValue[0].depthStencil.stencil; 1066 else 1067 if (isInInitialClearRange(m_isAttachmentFormat, 0u /* mipLevel */, arrayLayer, m_params.imageViewLayerRange)) 1068 { 1069 stencilValue = m_params.initValue.depthStencil.stencil; 1070 } 1071 else 1072 continue; 1073 1074 if (!comparePixelToStencilClearValue(image->getLevel(0), x, y, stencilValue, message)) 1075 return TestStatus::fail("Stencil value mismatch! " + message); 1076 } 1077 } 1078 } 1079 1080 if (!isDepthStencilFormat(m_params.imageFormat)) 1081 { 1082 for (deUint32 arrayLayer = 0; arrayLayer < m_params.imageLayerCount; ++arrayLayer) 1083 { 1084 de::MovePtr<TextureLevelPyramid> image = readImage(VK_IMAGE_ASPECT_COLOR_BIT, arrayLayer); 1085 std::string message; 1086 const VkClearColorValue* pColorValue; 1087 1088 for (deUint32 mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel) 1089 { 1090 const int clearColorNdx = (mipLevel < m_thresholdMipLevel ? 0 : 1); 1091 const VkExtent3D extent = getMipLevelExtent(m_params.imageExtent, mipLevel); 1092 1093 for (deUint32 z = 0; z < extent.depth; ++z) 1094 for (deUint32 y = 0; y < extent.height; ++y) 1095 for (deUint32 x = 0; x < extent.width; ++x) 1096 { 1097 if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange, m_params.clearLayerRange)) 1098 pColorValue = &m_params.clearValue[clearColorNdx].color; 1099 else 1100 { 1101 if (isInInitialClearRange(m_isAttachmentFormat, mipLevel, arrayLayer, m_params.imageViewLayerRange)) 1102 { 1103 pColorValue = &m_params.initValue.color; 1104 } 1105 else 1106 continue; 1107 } 1108 if (!comparePixelToColorClearValue(image->getLevel(mipLevel), x, y, z, *pColorValue, message)) 1109 return TestStatus::fail("Color value mismatch! " + message); 1110 } 1111 } 1112 } 1113 } 1114 1115 return TestStatus::pass(successMessage); 1116 } 1117 1118 void ImageClearingTestInstance::beginRenderPass (VkSubpassContents content, VkClearValue clearValue) const 1119 { 1120 const VkRenderPassBeginInfo renderPassBeginInfo = 1121 { 1122 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 1123 DE_NULL, // const void* pNext; 1124 *m_renderPass, // VkRenderPass renderPass; 1125 *m_frameBuffer, // VkFramebuffer framebuffer; 1126 { 1127 { 0, 0 }, // VkOffset2D offset; 1128 { 1129 m_params.imageExtent.width, // deUint32 width; 1130 m_params.imageExtent.height // deUint32 height; 1131 } // VkExtent2D extent; 1132 }, // VkRect2D renderArea; 1133 1u, // deUint32 clearValueCount; 1134 &clearValue // const VkClearValue* pClearValues; 1135 }; 1136 1137 m_vkd.cmdBeginRenderPass(*m_commandBuffer, &renderPassBeginInfo, content); 1138 } 1139 1140 class ClearColorImageTestInstance : public ImageClearingTestInstance 1141 { 1142 public: 1143 ClearColorImageTestInstance (Context& context, const TestParams& testParams) : ImageClearingTestInstance (context, testParams) {} 1144 TestStatus iterate (void); 1145 }; 1146 1147 TestStatus ClearColorImageTestInstance::iterate (void) 1148 { 1149 std::vector<VkImageSubresourceRange> subresourceRanges; 1150 1151 if (m_imageMipLevels == 1) 1152 subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, 1u, m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount)); 1153 else 1154 { 1155 subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, m_thresholdMipLevel, m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount)); 1156 subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, m_thresholdMipLevel, VK_REMAINING_MIP_LEVELS, m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount)); 1157 } 1158 1159 beginCommandBuffer(0); 1160 1161 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask 1162 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask 1163 0, // VkAccessFlags srcAccessMask 1164 (m_isAttachmentFormat 1165 ? VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT 1166 : VK_ACCESS_TRANSFER_WRITE_BIT), // VkAccessFlags dstAccessMask 1167 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1168 (m_isAttachmentFormat 1169 ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 1170 : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)); // VkImageLayout newLayout; 1171 1172 if (m_isAttachmentFormat) 1173 { 1174 beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue); 1175 m_vkd.cmdEndRenderPass(*m_commandBuffer); 1176 1177 pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // VkPipelineStageFlags srcStageMask 1178 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask 1179 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 1180 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask 1181 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 1182 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout; 1183 } 1184 1185 // Different clear color per range 1186 for (std::size_t i = 0u; i < subresourceRanges.size(); ++i) 1187 m_vkd.cmdClearColorImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_params.clearValue[i].color, 1, &subresourceRanges[i]); 1188 1189 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask 1190 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask 1191 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask 1192 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask 1193 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1194 VK_IMAGE_LAYOUT_GENERAL); // VkImageLayout newLayout; 1195 1196 endCommandBuffer(); 1197 submitCommandBuffer(); 1198 1199 return verifyResultImage("cmdClearColorImage passed"); 1200 } 1201 1202 class ClearDepthStencilImageTestInstance : public ImageClearingTestInstance 1203 { 1204 public: 1205 ClearDepthStencilImageTestInstance (Context& context, const TestParams& testParams) : ImageClearingTestInstance (context, testParams) {} 1206 TestStatus iterate (void); 1207 }; 1208 1209 TestStatus ClearDepthStencilImageTestInstance::iterate (void) 1210 { 1211 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(m_imageAspectFlags, 0u, 1u, m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount); 1212 1213 beginCommandBuffer(0); 1214 1215 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask 1216 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask 1217 0, // VkAccessFlags srcAccessMask 1218 (m_isAttachmentFormat 1219 ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT 1220 : VK_ACCESS_TRANSFER_WRITE_BIT), // VkAccessFlags dstAccessMask 1221 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1222 (m_isAttachmentFormat 1223 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL 1224 : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)); // VkImageLayout newLayout; 1225 1226 if (m_isAttachmentFormat) 1227 { 1228 beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue); 1229 m_vkd.cmdEndRenderPass(*m_commandBuffer); 1230 1231 pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // VkPipelineStageFlags srcStageMask 1232 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask 1233 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask 1234 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask 1235 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 1236 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout; 1237 } 1238 1239 m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_params.clearValue[0].depthStencil, 1, &subresourceRange); 1240 1241 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask 1242 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask 1243 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask 1244 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask 1245 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1246 VK_IMAGE_LAYOUT_GENERAL); // VkImageLayout newLayout; 1247 1248 endCommandBuffer(); 1249 submitCommandBuffer(); 1250 1251 return verifyResultImage("cmdClearDepthStencilImage passed"); 1252 } 1253 1254 class ClearAttachmentTestInstance : public ImageClearingTestInstance 1255 { 1256 public: 1257 enum ClearType 1258 { 1259 FULL_CLEAR, 1260 PARTIAL_CLEAR, 1261 }; 1262 1263 ClearAttachmentTestInstance (Context& context, const TestParams& testParams, const ClearType clearType = FULL_CLEAR) 1264 : ImageClearingTestInstance (context, testParams) 1265 , m_clearType (clearType) 1266 { 1267 if (!m_isAttachmentFormat) 1268 TCU_THROW(NotSupportedError, "Format not renderable"); 1269 } 1270 1271 TestStatus iterate (void) 1272 { 1273 const VkClearAttachment clearAttachment = 1274 { 1275 m_imageAspectFlags, // VkImageAspectFlags aspectMask; 1276 0u, // deUint32 colorAttachment; 1277 m_params.clearValue[0] // VkClearValue clearValue; 1278 }; 1279 1280 UVec4 clearCoords; 1281 std::vector<VkClearRect> clearRects; 1282 1283 if (m_clearType == FULL_CLEAR) 1284 { 1285 const VkClearRect rect = 1286 { 1287 { 1288 { 0, 0 }, // VkOffset2D offset; 1289 { m_params.imageExtent.width, m_params.imageExtent.height } // VkExtent2D extent; 1290 }, // VkRect2D rect; 1291 m_params.clearLayerRange.baseArrayLayer, // deUint32 baseArrayLayer; 1292 m_params.clearLayerRange.layerCount, // deUint32 layerCount; 1293 }; 1294 1295 clearRects.push_back(rect); 1296 } 1297 else 1298 { 1299 const deUint32 clearX = m_params.imageExtent.width / 4u; 1300 const deUint32 clearY = m_params.imageExtent.height / 4u; 1301 const deUint32 clearWidth = m_params.imageExtent.width / 2u; 1302 const deUint32 clearHeight = m_params.imageExtent.height / 2u; 1303 1304 clearCoords = UVec4(clearX, clearY, 1305 clearX + clearWidth, clearY + clearHeight); 1306 1307 const VkClearRect rects[2] = 1308 { 1309 { 1310 { 1311 { 0, static_cast<deInt32>(clearY) }, // VkOffset2D offset; 1312 { m_params.imageExtent.width, clearHeight } // VkExtent2D extent; 1313 }, // VkRect2D rect; 1314 m_params.clearLayerRange.baseArrayLayer, // deUint32 baseArrayLayer; 1315 m_params.clearLayerRange.layerCount // deUint32 layerCount; 1316 }, 1317 { 1318 { 1319 { static_cast<deInt32>(clearX), 0 }, // VkOffset2D offset; 1320 { clearWidth, m_params.imageExtent.height } // VkExtent2D extent; 1321 }, // VkRect2D rect; 1322 m_params.clearLayerRange.baseArrayLayer, // deUint32 baseArrayLayer; 1323 m_params.clearLayerRange.layerCount // deUint32 layerCount; 1324 } 1325 }; 1326 1327 clearRects.push_back(rects[0]); 1328 clearRects.push_back(rects[1]); 1329 } 1330 1331 const bool isDepthStencil = isDepthStencilFormat(m_params.imageFormat); 1332 const VkAccessFlags accessMask = (isDepthStencil ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); 1333 const VkImageLayout attachmentLayout = (isDepthStencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 1334 1335 beginCommandBuffer(0); 1336 1337 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask 1338 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask 1339 0, // VkAccessFlags srcAccessMask 1340 accessMask, // VkAccessFlags dstAccessMask 1341 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1342 attachmentLayout); // VkImageLayout newLayout; 1343 1344 beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue); 1345 m_vkd.cmdClearAttachments(*m_commandBuffer, 1, &clearAttachment, static_cast<deUint32>(clearRects.size()), &clearRects[0]); 1346 m_vkd.cmdEndRenderPass(*m_commandBuffer); 1347 1348 pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // VkPipelineStageFlags srcStageMask 1349 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask 1350 accessMask, // VkAccessFlags srcAccessMask 1351 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask 1352 attachmentLayout, // VkImageLayout oldLayout; 1353 VK_IMAGE_LAYOUT_GENERAL); // VkImageLayout newLayout; 1354 1355 endCommandBuffer(); 1356 submitCommandBuffer(); 1357 1358 return verifyResultImage("cmdClearAttachments passed", clearCoords); 1359 } 1360 1361 private: 1362 const ClearType m_clearType; 1363 }; 1364 1365 class PartialClearAttachmentTestInstance : public ClearAttachmentTestInstance 1366 { 1367 public: 1368 PartialClearAttachmentTestInstance (Context& context, const TestParams& testParams) : ClearAttachmentTestInstance (context, testParams, PARTIAL_CLEAR) {} 1369 }; 1370 1371 VkClearValue makeClearColorValue (VkFormat format, float r, float g, float b, float a) 1372 { 1373 const TextureFormat tcuFormat = mapVkFormat(format); 1374 VkClearValue clearValue; 1375 1376 if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_FLOATING_POINT 1377 || getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT 1378 || getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) 1379 { 1380 clearValue.color.float32[0] = r; 1381 clearValue.color.float32[1] = g; 1382 clearValue.color.float32[2] = b; 1383 clearValue.color.float32[3] = a; 1384 } 1385 else if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 1386 { 1387 UVec4 maxValues = getFormatMaxUintValue(tcuFormat); 1388 1389 clearValue.color.uint32[0] = (deUint32)((float)maxValues[0] * r); 1390 clearValue.color.uint32[1] = (deUint32)((float)maxValues[1] * g); 1391 clearValue.color.uint32[2] = (deUint32)((float)maxValues[2] * b); 1392 clearValue.color.uint32[3] = (deUint32)((float)maxValues[3] * a); 1393 } 1394 else if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_SIGNED_INTEGER) 1395 { 1396 IVec4 maxValues = getFormatMaxIntValue(tcuFormat); 1397 1398 clearValue.color.int32[0] = (deUint32)((float)maxValues[0] * r); 1399 clearValue.color.int32[1] = (deUint32)((float)maxValues[1] * g); 1400 clearValue.color.int32[2] = (deUint32)((float)maxValues[2] * b); 1401 clearValue.color.int32[3] = (deUint32)((float)maxValues[3] * a); 1402 } 1403 else 1404 DE_FATAL("Unknown channel class"); 1405 1406 return clearValue; 1407 } 1408 1409 std::string getFormatCaseName (VkFormat format) 1410 { 1411 return de::toLower(de::toString(getFormatStr(format)).substr(10)); 1412 } 1413 1414 const char* getImageTypeCaseName (VkImageType type) 1415 { 1416 const char* s_names[] = 1417 { 1418 "1d", 1419 "2d", 1420 "3d" 1421 }; 1422 return de::getSizedArrayElement<VK_IMAGE_TYPE_LAST>(s_names, type); 1423 } 1424 1425 TestCaseGroup* createImageClearingTestsCommon (TestContext& testCtx, tcu::TestCaseGroup* imageClearingTests, AllocationKind allocationKind) 1426 { 1427 de::MovePtr<TestCaseGroup> colorImageClearTests (new TestCaseGroup(testCtx, "clear_color_image", "Color Image Clear Tests")); 1428 de::MovePtr<TestCaseGroup> depthStencilImageClearTests (new TestCaseGroup(testCtx, "clear_depth_stencil_image", "Color Depth/Stencil Image Tests")); 1429 de::MovePtr<TestCaseGroup> colorAttachmentClearTests (new TestCaseGroup(testCtx, "clear_color_attachment", "Color Color Attachment Tests")); 1430 de::MovePtr<TestCaseGroup> depthStencilAttachmentClearTests (new TestCaseGroup(testCtx, "clear_depth_stencil_attachment", "Color Depth/Stencil Attachment Tests")); 1431 de::MovePtr<TestCaseGroup> partialColorAttachmentClearTests (new TestCaseGroup(testCtx, "partial_clear_color_attachment", "Clear Partial Color Attachment Tests")); 1432 de::MovePtr<TestCaseGroup> partialDepthStencilAttachmentClearTests (new TestCaseGroup(testCtx, "partial_clear_depth_stencil_attachment", "Clear Partial Depth/Stencil Attachment Tests")); 1433 1434 // Some formats are commented out due to the tcu::TextureFormat does not support them yet. 1435 const VkFormat colorImageFormatsToTest[] = 1436 { 1437 VK_FORMAT_R4G4_UNORM_PACK8, 1438 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 1439 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 1440 VK_FORMAT_R5G6B5_UNORM_PACK16, 1441 VK_FORMAT_B5G6R5_UNORM_PACK16, 1442 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 1443 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 1444 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 1445 VK_FORMAT_R8_UNORM, 1446 VK_FORMAT_R8_SNORM, 1447 VK_FORMAT_R8_USCALED, 1448 VK_FORMAT_R8_SSCALED, 1449 VK_FORMAT_R8_UINT, 1450 VK_FORMAT_R8_SINT, 1451 VK_FORMAT_R8_SRGB, 1452 VK_FORMAT_R8G8_UNORM, 1453 VK_FORMAT_R8G8_SNORM, 1454 VK_FORMAT_R8G8_USCALED, 1455 VK_FORMAT_R8G8_SSCALED, 1456 VK_FORMAT_R8G8_UINT, 1457 VK_FORMAT_R8G8_SINT, 1458 VK_FORMAT_R8G8_SRGB, 1459 VK_FORMAT_R8G8B8_UNORM, 1460 VK_FORMAT_R8G8B8_SNORM, 1461 VK_FORMAT_R8G8B8_USCALED, 1462 VK_FORMAT_R8G8B8_SSCALED, 1463 VK_FORMAT_R8G8B8_UINT, 1464 VK_FORMAT_R8G8B8_SINT, 1465 VK_FORMAT_R8G8B8_SRGB, 1466 VK_FORMAT_B8G8R8_UNORM, 1467 VK_FORMAT_B8G8R8_SNORM, 1468 VK_FORMAT_B8G8R8_USCALED, 1469 VK_FORMAT_B8G8R8_SSCALED, 1470 VK_FORMAT_B8G8R8_UINT, 1471 VK_FORMAT_B8G8R8_SINT, 1472 VK_FORMAT_B8G8R8_SRGB, 1473 VK_FORMAT_R8G8B8A8_UNORM, 1474 VK_FORMAT_R8G8B8A8_SNORM, 1475 VK_FORMAT_R8G8B8A8_USCALED, 1476 VK_FORMAT_R8G8B8A8_SSCALED, 1477 VK_FORMAT_R8G8B8A8_UINT, 1478 VK_FORMAT_R8G8B8A8_SINT, 1479 VK_FORMAT_R8G8B8A8_SRGB, 1480 VK_FORMAT_B8G8R8A8_UNORM, 1481 VK_FORMAT_B8G8R8A8_SNORM, 1482 VK_FORMAT_B8G8R8A8_USCALED, 1483 VK_FORMAT_B8G8R8A8_SSCALED, 1484 VK_FORMAT_B8G8R8A8_UINT, 1485 VK_FORMAT_B8G8R8A8_SINT, 1486 VK_FORMAT_B8G8R8A8_SRGB, 1487 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 1488 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 1489 VK_FORMAT_A8B8G8R8_USCALED_PACK32, 1490 VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 1491 VK_FORMAT_A8B8G8R8_UINT_PACK32, 1492 VK_FORMAT_A8B8G8R8_SINT_PACK32, 1493 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 1494 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 1495 VK_FORMAT_A2R10G10B10_SNORM_PACK32, 1496 VK_FORMAT_A2R10G10B10_USCALED_PACK32, 1497 VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 1498 VK_FORMAT_A2R10G10B10_UINT_PACK32, 1499 VK_FORMAT_A2R10G10B10_SINT_PACK32, 1500 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 1501 VK_FORMAT_A2B10G10R10_SNORM_PACK32, 1502 VK_FORMAT_A2B10G10R10_USCALED_PACK32, 1503 VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 1504 VK_FORMAT_A2B10G10R10_UINT_PACK32, 1505 VK_FORMAT_A2B10G10R10_SINT_PACK32, 1506 VK_FORMAT_R16_UNORM, 1507 VK_FORMAT_R16_SNORM, 1508 VK_FORMAT_R16_USCALED, 1509 VK_FORMAT_R16_SSCALED, 1510 VK_FORMAT_R16_UINT, 1511 VK_FORMAT_R16_SINT, 1512 VK_FORMAT_R16_SFLOAT, 1513 VK_FORMAT_R16G16_UNORM, 1514 VK_FORMAT_R16G16_SNORM, 1515 VK_FORMAT_R16G16_USCALED, 1516 VK_FORMAT_R16G16_SSCALED, 1517 VK_FORMAT_R16G16_UINT, 1518 VK_FORMAT_R16G16_SINT, 1519 VK_FORMAT_R16G16_SFLOAT, 1520 VK_FORMAT_R16G16B16_UNORM, 1521 VK_FORMAT_R16G16B16_SNORM, 1522 VK_FORMAT_R16G16B16_USCALED, 1523 VK_FORMAT_R16G16B16_SSCALED, 1524 VK_FORMAT_R16G16B16_UINT, 1525 VK_FORMAT_R16G16B16_SINT, 1526 VK_FORMAT_R16G16B16_SFLOAT, 1527 VK_FORMAT_R16G16B16A16_UNORM, 1528 VK_FORMAT_R16G16B16A16_SNORM, 1529 VK_FORMAT_R16G16B16A16_USCALED, 1530 VK_FORMAT_R16G16B16A16_SSCALED, 1531 VK_FORMAT_R16G16B16A16_UINT, 1532 VK_FORMAT_R16G16B16A16_SINT, 1533 VK_FORMAT_R16G16B16A16_SFLOAT, 1534 VK_FORMAT_R32_UINT, 1535 VK_FORMAT_R32_SINT, 1536 VK_FORMAT_R32_SFLOAT, 1537 VK_FORMAT_R32G32_UINT, 1538 VK_FORMAT_R32G32_SINT, 1539 VK_FORMAT_R32G32_SFLOAT, 1540 VK_FORMAT_R32G32B32_UINT, 1541 VK_FORMAT_R32G32B32_SINT, 1542 VK_FORMAT_R32G32B32_SFLOAT, 1543 VK_FORMAT_R32G32B32A32_UINT, 1544 VK_FORMAT_R32G32B32A32_SINT, 1545 VK_FORMAT_R32G32B32A32_SFLOAT, 1546 // VK_FORMAT_R64_UINT, 1547 // VK_FORMAT_R64_SINT, 1548 // VK_FORMAT_R64_SFLOAT, 1549 // VK_FORMAT_R64G64_UINT, 1550 // VK_FORMAT_R64G64_SINT, 1551 // VK_FORMAT_R64G64_SFLOAT, 1552 // VK_FORMAT_R64G64B64_UINT, 1553 // VK_FORMAT_R64G64B64_SINT, 1554 // VK_FORMAT_R64G64B64_SFLOAT, 1555 // VK_FORMAT_R64G64B64A64_UINT, 1556 // VK_FORMAT_R64G64B64A64_SINT, 1557 // VK_FORMAT_R64G64B64A64_SFLOAT, 1558 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 1559 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 1560 // VK_FORMAT_BC1_RGB_UNORM_BLOCK, 1561 // VK_FORMAT_BC1_RGB_SRGB_BLOCK, 1562 // VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1563 // VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 1564 // VK_FORMAT_BC2_UNORM_BLOCK, 1565 // VK_FORMAT_BC2_SRGB_BLOCK, 1566 // VK_FORMAT_BC3_UNORM_BLOCK, 1567 // VK_FORMAT_BC3_SRGB_BLOCK, 1568 // VK_FORMAT_BC4_UNORM_BLOCK, 1569 // VK_FORMAT_BC4_SNORM_BLOCK, 1570 // VK_FORMAT_BC5_UNORM_BLOCK, 1571 // VK_FORMAT_BC5_SNORM_BLOCK, 1572 // VK_FORMAT_BC6H_UFLOAT_BLOCK, 1573 // VK_FORMAT_BC6H_SFLOAT_BLOCK, 1574 // VK_FORMAT_BC7_UNORM_BLOCK, 1575 // VK_FORMAT_BC7_SRGB_BLOCK, 1576 // VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 1577 // VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 1578 // VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 1579 // VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 1580 // VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 1581 // VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 1582 // VK_FORMAT_EAC_R11_UNORM_BLOCK, 1583 // VK_FORMAT_EAC_R11_SNORM_BLOCK, 1584 // VK_FORMAT_EAC_R11G11_UNORM_BLOCK, 1585 // VK_FORMAT_EAC_R11G11_SNORM_BLOCK, 1586 // VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 1587 // VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 1588 // VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 1589 // VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 1590 // VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 1591 // VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 1592 // VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 1593 // VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 1594 // VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 1595 // VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 1596 // VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 1597 // VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 1598 // VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 1599 // VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 1600 // VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 1601 // VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 1602 // VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 1603 // VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 1604 // VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 1605 // VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 1606 // VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 1607 // VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 1608 // VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 1609 // VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 1610 // VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 1611 // VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 1612 // VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 1613 // VK_FORMAT_ASTC_12x12_SRGB_BLOCK 1614 }; 1615 const size_t numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); 1616 1617 const VkFormat depthStencilImageFormatsToTest[] = 1618 { 1619 VK_FORMAT_D16_UNORM, 1620 VK_FORMAT_X8_D24_UNORM_PACK32, 1621 VK_FORMAT_D32_SFLOAT, 1622 VK_FORMAT_S8_UINT, 1623 VK_FORMAT_D16_UNORM_S8_UINT, 1624 VK_FORMAT_D24_UNORM_S8_UINT, 1625 VK_FORMAT_D32_SFLOAT_S8_UINT 1626 }; 1627 const size_t numOfDepthStencilImageFormatsToTest = DE_LENGTH_OF_ARRAY(depthStencilImageFormatsToTest); 1628 1629 struct ImageLayerParams 1630 { 1631 deUint32 imageLayerCount; 1632 LayerRange imageViewRange; 1633 LayerRange clearLayerRange; 1634 const char* testName; 1635 }; 1636 const ImageLayerParams imageLayerParamsToTest[] = 1637 { 1638 { 1639 1u, // imageLayerCount 1640 {0u, 1u}, // imageViewRange 1641 {0u, 1u}, // clearLayerRange 1642 DE_NULL // testName 1643 }, 1644 { 1645 16u, // imageLayerCount 1646 {3u, 12u}, // imageViewRange 1647 {2u, 5u}, // clearLayerRange 1648 "multiple_layers" // testName 1649 }, 1650 }; 1651 1652 const size_t numOfImageLayerParamsToTest = DE_LENGTH_OF_ARRAY(imageLayerParamsToTest); 1653 1654 // Clear color image 1655 { 1656 const VkImageType imageTypesToTest[] = 1657 { 1658 VK_IMAGE_TYPE_1D, 1659 VK_IMAGE_TYPE_2D, 1660 VK_IMAGE_TYPE_3D 1661 }; 1662 const size_t numOfImageTypesToTest = DE_LENGTH_OF_ARRAY(imageTypesToTest); 1663 1664 const VkExtent3D imageDimensionsByType[] = 1665 { 1666 { 256, 1, 1}, 1667 { 256, 256, 1}, 1668 { 256, 256, 16} 1669 }; 1670 1671 for (size_t imageTypeIndex = 0; imageTypeIndex < numOfImageTypesToTest; ++imageTypeIndex) 1672 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfColorImageFormatsToTest; ++imageFormatIndex) 1673 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest; ++imageLayerParamsIndex) 1674 { 1675 1676 if (imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount > 1u && imageTypesToTest[imageTypeIndex] == VK_IMAGE_TYPE_3D) 1677 { 1678 // 3D ARRAY images are not supported 1679 continue; 1680 } 1681 1682 const VkFormat format = colorImageFormatsToTest[imageFormatIndex]; 1683 const TestParams testParams = 1684 { 1685 false, // bool useSingleMipLevel; 1686 imageTypesToTest[imageTypeIndex], // VkImageType imageType; 1687 format, // VkFormat imageFormat; 1688 imageDimensionsByType[imageTypeIndex], // VkExtent3D imageExtent; 1689 imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount, // deUint32 imageLayerCount; 1690 { 1691 0u, 1692 imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount 1693 }, // LayerRange imageViewLayerRange; 1694 makeClearColorValue(format, 0.2f, 0.1f, 0.7f, 0.8f), // VkClearValue initValue; 1695 { 1696 makeClearColorValue(format, 0.1f, 0.5f, 0.3f, 0.9f), // VkClearValue clearValue[0]; 1697 makeClearColorValue(format, 0.3f, 0.6f, 0.2f, 0.7f), // VkClearValue clearValue[1]; 1698 }, 1699 imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange, // LayerRange clearLayerRange; 1700 allocationKind // AllocationKind allocationKind; 1701 }; 1702 1703 std::ostringstream testCaseName; 1704 testCaseName << getImageTypeCaseName(testParams.imageType) << "_" << getFormatCaseName(format); 1705 if (imageLayerParamsToTest[imageLayerParamsIndex].testName != DE_NULL) 1706 testCaseName << "_" << imageLayerParamsToTest[imageLayerParamsIndex].testName; 1707 1708 colorImageClearTests->addChild(new InstanceFactory1<ClearColorImageTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName.str(), "Clear Color Image", testParams)); 1709 } 1710 1711 imageClearingTests->addChild(colorImageClearTests.release()); 1712 } 1713 1714 // Clear depth/stencil image 1715 { 1716 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfDepthStencilImageFormatsToTest; ++imageFormatIndex) 1717 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest; ++imageLayerParamsIndex) 1718 { 1719 const TestParams testParams = 1720 { 1721 true, // bool useSingleMipLevel; 1722 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1723 depthStencilImageFormatsToTest[imageFormatIndex], // VkFormat format; 1724 { 256, 256, 1 }, // VkExtent3D extent; 1725 imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount, // deUint32 imageLayerCount; 1726 { 1727 0u, 1728 imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount 1729 }, // LayerRange imageViewLayerRange; 1730 makeClearValueDepthStencil(0.5f, 0x03), // VkClearValue initValue 1731 { 1732 makeClearValueDepthStencil(0.1f, 0x06), // VkClearValue clearValue[0]; 1733 makeClearValueDepthStencil(0.3f, 0x04), // VkClearValue clearValue[1]; 1734 }, 1735 imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange, // LayerRange clearLayerRange; 1736 allocationKind // AllocationKind allocationKind; 1737 }; 1738 1739 std::ostringstream testCaseName; 1740 testCaseName << getImageTypeCaseName(testParams.imageType) << "_" << getFormatCaseName(testParams.imageFormat); 1741 if (imageLayerParamsToTest[imageLayerParamsIndex].testName != DE_NULL) 1742 testCaseName << "_" << imageLayerParamsToTest[imageLayerParamsIndex].testName; 1743 1744 depthStencilImageClearTests->addChild(new InstanceFactory1<ClearDepthStencilImageTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName.str(), "Clear Depth/Stencil Image", testParams)); 1745 } 1746 1747 imageClearingTests->addChild(depthStencilImageClearTests.release()); 1748 } 1749 1750 // Clear color attachment 1751 { 1752 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfColorImageFormatsToTest; ++imageFormatIndex) 1753 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest; ++imageLayerParamsIndex) 1754 { 1755 const VkFormat format = colorImageFormatsToTest[imageFormatIndex]; 1756 1757 const TestParams testParams = 1758 { 1759 true, // bool useSingleMipLevel; 1760 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1761 format, // VkFormat format; 1762 { 256, 256, 1 }, // VkExtent3D extent; 1763 imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount, // deUint32 imageLayerCount; 1764 imageLayerParamsToTest[imageLayerParamsIndex].imageViewRange, // LayerRange imageViewLayerRange; 1765 makeClearColorValue(format, 0.2f, 0.1f, 0.7f, 0.8f), // VkClearValue initValue 1766 { 1767 makeClearColorValue(format, 0.1f, 0.5f, 0.3f, 0.9f), // VkClearValue clearValue[0]; 1768 makeClearColorValue(format, 0.3f, 0.6f, 0.2f, 0.7f), // VkClearValue clearValue[1]; 1769 }, 1770 imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange, // LayerRange clearLayerRange; 1771 allocationKind // AllocationKind allocationKind; 1772 }; 1773 1774 std::ostringstream testCaseName; 1775 testCaseName << getImageTypeCaseName(testParams.imageType) << "_" << getFormatCaseName(format); 1776 if (imageLayerParamsToTest[imageLayerParamsIndex].testName != DE_NULL) 1777 testCaseName << "_" << imageLayerParamsToTest[imageLayerParamsIndex].testName; 1778 1779 colorAttachmentClearTests->addChild(new InstanceFactory1<ClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName.str(), "Clear Color Attachment", testParams)); 1780 partialColorAttachmentClearTests->addChild(new InstanceFactory1<PartialClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName.str(), "Partial Clear Color Attachment", testParams)); 1781 } 1782 1783 imageClearingTests->addChild(colorAttachmentClearTests.release()); 1784 imageClearingTests->addChild(partialColorAttachmentClearTests.release()); 1785 } 1786 1787 // Clear depth/stencil attachment 1788 { 1789 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfDepthStencilImageFormatsToTest; ++imageFormatIndex) 1790 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest; ++imageLayerParamsIndex) 1791 { 1792 const TestParams testParams = 1793 { 1794 true, // bool useSingleMipLevel; 1795 VK_IMAGE_TYPE_2D, // VkImageType imageType; 1796 depthStencilImageFormatsToTest[imageFormatIndex], // VkFormat format; 1797 { 256, 256, 1 }, // VkExtent3D extent; 1798 imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount, // deUint32 imageLayerCount; 1799 imageLayerParamsToTest[imageLayerParamsIndex].imageViewRange, // LayerRange imageViewLayerRange; 1800 makeClearValueDepthStencil(0.5f, 0x03), // VkClearValue initValue 1801 { 1802 makeClearValueDepthStencil(0.1f, 0x06), // VkClearValue clearValue[0]; 1803 makeClearValueDepthStencil(0.3f, 0x04), // VkClearValue clearValue[1]; 1804 }, 1805 imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange, // LayerRange clearLayerRange; 1806 allocationKind // AllocationKind allocationKind; 1807 }; 1808 1809 std::ostringstream testCaseName; 1810 testCaseName << getImageTypeCaseName(testParams.imageType) << "_" << getFormatCaseName(testParams.imageFormat); 1811 if (imageLayerParamsToTest[imageLayerParamsIndex].testName != DE_NULL) 1812 testCaseName << "_" << imageLayerParamsToTest[imageLayerParamsIndex].testName; 1813 1814 depthStencilAttachmentClearTests->addChild(new InstanceFactory1<ClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName.str(), "Clear Depth/Stencil Attachment", testParams)); 1815 partialDepthStencilAttachmentClearTests->addChild(new InstanceFactory1<PartialClearAttachmentTestInstance, TestParams>(testCtx, NODETYPE_SELF_VALIDATE, testCaseName.str(), "Parital Clear Depth/Stencil Attachment", testParams)); 1816 } 1817 1818 imageClearingTests->addChild(depthStencilAttachmentClearTests.release()); 1819 imageClearingTests->addChild(partialDepthStencilAttachmentClearTests.release()); 1820 } 1821 1822 return imageClearingTests; 1823 } 1824 1825 void createCoreImageClearingTests (tcu::TestCaseGroup* group) 1826 { 1827 createImageClearingTestsCommon(group->getTestContext(), group, ALLOCATION_KIND_SUBALLOCATED); 1828 } 1829 1830 void createDedicatedAllocationImageClearingTests (tcu::TestCaseGroup* group) 1831 { 1832 createImageClearingTestsCommon(group->getTestContext(), group, ALLOCATION_KIND_DEDICATED); 1833 } 1834 1835 } // anonymous 1836 1837 TestCaseGroup* createImageClearingTests (TestContext& testCtx) 1838 { 1839 de::MovePtr<TestCaseGroup> imageClearingTests (new TestCaseGroup(testCtx, "image_clearing", "Image Clearing Tests")); 1840 1841 imageClearingTests->addChild(createTestGroup(testCtx, "core", "Core Image Clearing Tests", createCoreImageClearingTests)); 1842 imageClearingTests->addChild(createTestGroup(testCtx, "dedicated_allocation", "Image Clearing Tests For Dedicated Memory Allocation", createDedicatedAllocationImageClearingTests)); 1843 1844 return imageClearingTests.release(); 1845 } 1846 1847 } // api 1848 } // vkt 1849