1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015-2016 The Khronos Group Inc. 6 * Copyright (c) 2015-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 Copies And Blitting Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktApiCopiesAndBlittingTests.hpp" 26 27 #include "deStringUtil.hpp" 28 #include "deUniquePtr.hpp" 29 30 #include "tcuImageCompare.hpp" 31 #include "tcuTexture.hpp" 32 #include "tcuTextureUtil.hpp" 33 #include "tcuVectorType.hpp" 34 #include "tcuVectorUtil.hpp" 35 #include "tcuTestLog.hpp" 36 #include "tcuTexLookupVerifier.hpp" 37 38 #include "vkImageUtil.hpp" 39 #include "vkMemUtil.hpp" 40 #include "vkPrograms.hpp" 41 #include "vkQueryUtil.hpp" 42 #include "vkRefUtil.hpp" 43 #include "vktTestCase.hpp" 44 #include "vktTestCaseUtil.hpp" 45 #include "vktTestGroupUtil.hpp" 46 #include "vkTypeUtil.hpp" 47 48 #include <set> 49 50 namespace vkt 51 { 52 53 namespace api 54 { 55 56 namespace 57 { 58 enum MirrorMode 59 { 60 MIRROR_MODE_NONE = 0, 61 MIRROR_MODE_X = (1<<0), 62 MIRROR_MODE_Y = (1<<1), 63 MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y, 64 65 MIRROR_MODE_LAST 66 }; 67 68 enum AllocationKind 69 { 70 ALLOCATION_KIND_SUBALLOCATED, 71 ALLOCATION_KIND_DEDICATED, 72 }; 73 74 template <typename Type> 75 class BinaryCompare 76 { 77 public: 78 bool operator() (const Type& a, const Type& b) const 79 { 80 return deMemCmp(&a, &b, sizeof(Type)) < 0; 81 } 82 }; 83 84 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> > FormatSet; 85 86 FormatSet dedicatedAllocationImageToImageFormatsToTestSet; 87 FormatSet dedicatedAllocationBlittingFormatsToTestSet; 88 89 using namespace vk; 90 91 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format) 92 { 93 VkImageAspectFlags aspectFlag = 0; 94 aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0); 95 aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0); 96 97 if (!aspectFlag) 98 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT; 99 100 return aspectFlag; 101 } 102 103 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format)) 104 // except that it supports some formats that are not mappable to VkFormat. 105 // When we are checking combined depth and stencil formats, each aspect is 106 // checked separately, and in some cases we construct PBA with a format that 107 // is not mappable to VkFormat. 108 bool isFloatFormat (tcu::TextureFormat format) 109 { 110 return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT; 111 } 112 113 union CopyRegion 114 { 115 VkBufferCopy bufferCopy; 116 VkImageCopy imageCopy; 117 VkBufferImageCopy bufferImageCopy; 118 VkImageBlit imageBlit; 119 VkImageResolve imageResolve; 120 }; 121 122 struct ImageParms 123 { 124 VkImageType imageType; 125 VkFormat format; 126 VkExtent3D extent; 127 VkImageLayout operationLayout; 128 }; 129 130 struct TestParams 131 { 132 union Data 133 { 134 struct Buffer 135 { 136 VkDeviceSize size; 137 } buffer; 138 139 ImageParms image; 140 } src, dst; 141 142 std::vector<CopyRegion> regions; 143 144 union 145 { 146 VkFilter filter; 147 VkSampleCountFlagBits samples; 148 }; 149 150 AllocationKind allocationKind; 151 deUint32 mipLevels; 152 deBool singleCommand; 153 154 TestParams (void) 155 { 156 mipLevels = 1u; 157 singleCommand = DE_TRUE; 158 } 159 }; 160 161 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki, 162 const DeviceInterface& vkd, 163 const VkPhysicalDevice& physDevice, 164 const VkDevice device, 165 const VkBuffer& buffer, 166 const MemoryRequirement requirement, 167 Allocator& allocator, 168 AllocationKind allocationKind) 169 { 170 switch (allocationKind) 171 { 172 case ALLOCATION_KIND_SUBALLOCATED: 173 { 174 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer); 175 176 return allocator.allocate(memoryRequirements, requirement); 177 } 178 179 case ALLOCATION_KIND_DEDICATED: 180 { 181 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement); 182 } 183 184 default: 185 { 186 TCU_THROW(InternalError, "Invalid allocation kind"); 187 } 188 } 189 } 190 191 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki, 192 const DeviceInterface& vkd, 193 const VkPhysicalDevice& physDevice, 194 const VkDevice device, 195 const VkImage& image, 196 const MemoryRequirement requirement, 197 Allocator& allocator, 198 AllocationKind allocationKind) 199 { 200 switch (allocationKind) 201 { 202 case ALLOCATION_KIND_SUBALLOCATED: 203 { 204 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image); 205 206 return allocator.allocate(memoryRequirements, requirement); 207 } 208 209 case ALLOCATION_KIND_DEDICATED: 210 { 211 return allocateDedicated(vki, vkd, physDevice, device, image, requirement); 212 } 213 214 default: 215 { 216 TCU_THROW(InternalError, "Invalid allocation kind"); 217 } 218 } 219 } 220 221 222 inline deUint32 getArraySize(const ImageParms& parms) 223 { 224 return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u; 225 } 226 227 inline VkExtent3D getExtent3D(const ImageParms& parms) 228 { 229 const VkExtent3D extent = 230 { 231 parms.extent.width, 232 parms.extent.height, 233 (parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth 234 }; 235 return extent; 236 } 237 238 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat) 239 { 240 tcu::TextureFormat format; 241 switch (combinedFormat.type) 242 { 243 case tcu::TextureFormat::UNSIGNED_INT_16_8_8: 244 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16); 245 break; 246 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV: 247 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV); 248 break; 249 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 250 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT); 251 break; 252 default: 253 DE_ASSERT(false); 254 break; 255 } 256 return format; 257 } 258 259 class CopiesAndBlittingTestInstance : public vkt::TestInstance 260 { 261 public: 262 CopiesAndBlittingTestInstance (Context& context, 263 TestParams testParams); 264 virtual tcu::TestStatus iterate (void) = 0; 265 266 enum FillMode 267 { 268 FILL_MODE_GRADIENT = 0, 269 FILL_MODE_WHITE, 270 FILL_MODE_RED, 271 FILL_MODE_MULTISAMPLE, 272 273 FILL_MODE_LAST 274 }; 275 276 protected: 277 const TestParams m_params; 278 279 Move<VkCommandPool> m_cmdPool; 280 Move<VkCommandBuffer> m_cmdBuffer; 281 Move<VkFence> m_fence; 282 de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel; 283 de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel; 284 de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel[16]; 285 286 VkCommandBufferBeginInfo m_cmdBufferBeginInfo; 287 288 void generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT); 289 virtual void generateExpectedResult (void); 290 void uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc); 291 void uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u); 292 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result); 293 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0; 294 deUint32 calculateSize (tcu::ConstPixelBufferAccess src) const 295 { 296 return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat()); 297 } 298 299 de::MovePtr<tcu::TextureLevel> readImage (vk::VkImage image, 300 const ImageParms& imageParms, 301 const deUint32 mipLevel = 0u); 302 void submitCommandsAndWait (const DeviceInterface& vk, 303 const VkDevice device, 304 const VkQueue queue, 305 const VkCommandBuffer& cmdBuffer); 306 307 private: 308 void uploadImageAspect (const tcu::ConstPixelBufferAccess& src, 309 const VkImage& dst, 310 const ImageParms& parms, 311 const deUint32 mipLevels = 1u); 312 void readImageAspect (vk::VkImage src, 313 const tcu::PixelBufferAccess& dst, 314 const ImageParms& parms, 315 const deUint32 mipLevel = 0u); 316 }; 317 318 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams) 319 : vkt::TestInstance (context) 320 , m_params (testParams) 321 { 322 const DeviceInterface& vk = context.getDeviceInterface(); 323 const VkDevice vkDevice = context.getDevice(); 324 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 325 326 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED) 327 { 328 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation")) 329 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported"); 330 } 331 332 // Create command pool 333 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex); 334 335 // Create command buffer 336 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 337 338 // Create fence 339 m_fence = createFence(vk, vkDevice); 340 } 341 342 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode) 343 { 344 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type); 345 tcu::Vec4 maxValue (1.0f); 346 347 if (buffer.getFormat().order == tcu::TextureFormat::S) 348 { 349 // Stencil-only is stored in the first component. Stencil is always 8 bits. 350 maxValue.x() = 1 << 8; 351 } 352 else if (buffer.getFormat().order == tcu::TextureFormat::DS) 353 { 354 // In a combined format, fillWithComponentGradients expects stencil in the fourth component. 355 maxValue.w() = 1 << 8; 356 } 357 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 358 { 359 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that. 360 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32)); 361 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0); 362 363 for (int i = 0; i < 4; ++i) 364 { 365 if (bits[i] != 0) 366 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1); 367 } 368 } 369 370 if (mode == FILL_MODE_GRADIENT) 371 { 372 tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue); 373 return; 374 } 375 376 const tcu::Vec4 redColor (maxValue.x(), 0.0, 0.0, maxValue.w()); 377 const tcu::Vec4 greenColor (0.0, maxValue.y(), 0.0, maxValue.w()); 378 const tcu::Vec4 blueColor (0.0, 0.0, maxValue.z(), maxValue.w()); 379 const tcu::Vec4 whiteColor (maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w()); 380 381 for (int z = 0; z < depth; ++z) 382 for (int y = 0; y < height; ++y) 383 for (int x = 0; x < width; ++x) 384 { 385 switch (mode) 386 { 387 case FILL_MODE_WHITE: 388 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type)) 389 { 390 buffer.setPixDepth(1.0f, x, y, z); 391 if (tcu::hasStencilComponent(buffer.getFormat().order)) 392 buffer.setPixStencil(255, x, y, z); 393 } 394 else 395 buffer.setPixel(whiteColor, x, y, z); 396 break; 397 398 case FILL_MODE_RED: 399 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type)) 400 { 401 buffer.setPixDepth(redColor[0], x, y, z); 402 if (tcu::hasStencilComponent(buffer.getFormat().order)) 403 buffer.setPixStencil((int)redColor[3], x, y, z); 404 } 405 else 406 buffer.setPixel(redColor, x, y, z); 407 break; 408 409 case FILL_MODE_MULTISAMPLE: 410 { 411 float xScaled = static_cast<float>(x) / static_cast<float>(width); 412 float yScaled = static_cast<float>(y) / static_cast<float>(height); 413 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z); 414 break; 415 } 416 417 default: 418 break; 419 } 420 } 421 } 422 423 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc) 424 { 425 const DeviceInterface& vk = m_context.getDeviceInterface(); 426 const VkDevice vkDevice = m_context.getDevice(); 427 const deUint32 bufferSize = calculateSize(bufferAccess); 428 429 // Write buffer data 430 deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize); 431 flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize); 432 } 433 434 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels) 435 { 436 const InstanceInterface& vki = m_context.getInstanceInterface(); 437 const DeviceInterface& vk = m_context.getDeviceInterface(); 438 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice(); 439 const VkDevice vkDevice = m_context.getDevice(); 440 const VkQueue queue = m_context.getUniversalQueue(); 441 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 442 Allocator& memAlloc = m_context.getDefaultAllocator(); 443 Move<VkBuffer> buffer; 444 const deUint32 bufferSize = calculateSize(imageAccess); 445 de::MovePtr<Allocation> bufferAlloc; 446 const deUint32 arraySize = getArraySize(parms); 447 const VkExtent3D imageExtent = getExtent3D(parms); 448 std::vector <VkBufferImageCopy> copyRegions; 449 450 // Create source buffer 451 { 452 const VkBufferCreateInfo bufferParams = 453 { 454 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 455 DE_NULL, // const void* pNext; 456 0u, // VkBufferCreateFlags flags; 457 bufferSize, // VkDeviceSize size; 458 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 459 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 460 1u, // deUint32 queueFamilyIndexCount; 461 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 462 }; 463 464 buffer = createBuffer(vk, vkDevice, &bufferParams); 465 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); 466 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 467 } 468 469 // Barriers for copying buffer to image 470 const VkBufferMemoryBarrier preBufferBarrier = 471 { 472 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 473 DE_NULL, // const void* pNext; 474 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 475 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 476 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 477 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 478 *buffer, // VkBuffer buffer; 479 0u, // VkDeviceSize offset; 480 bufferSize // VkDeviceSize size; 481 }; 482 483 const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(parms.format)); 484 const bool skipPreImageBarrier = formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) && 485 getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT; 486 const VkImageMemoryBarrier preImageBarrier = 487 { 488 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 489 DE_NULL, // const void* pNext; 490 0u, // VkAccessFlags srcAccessMask; 491 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 492 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 493 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 494 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 495 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 496 image, // VkImage image; 497 { // VkImageSubresourceRange subresourceRange; 498 formatAspect, // VkImageAspectFlags aspect; 499 0u, // deUint32 baseMipLevel; 500 mipLevels, // deUint32 mipLevels; 501 0u, // deUint32 baseArraySlice; 502 arraySize, // deUint32 arraySize; 503 } 504 }; 505 506 const VkImageMemoryBarrier postImageBarrier = 507 { 508 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 509 DE_NULL, // const void* pNext; 510 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 511 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 512 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 513 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 514 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 515 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 516 image, // VkImage image; 517 { // VkImageSubresourceRange subresourceRange; 518 formatAspect, // VkImageAspectFlags aspect; 519 0u, // deUint32 baseMipLevel; 520 mipLevels, // deUint32 mipLevels; 521 0u, // deUint32 baseArraySlice; 522 arraySize, // deUint32 arraySize; 523 } 524 }; 525 526 for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++) 527 { 528 const VkExtent3D copyExtent = 529 { 530 imageExtent.width >> mipLevelNdx, 531 imageExtent.height >> mipLevelNdx, 532 imageExtent.depth 533 }; 534 535 const VkBufferImageCopy copyRegion = 536 { 537 0u, // VkDeviceSize bufferOffset; 538 (deUint32)imageAccess.getWidth(), // deUint32 bufferRowLength; 539 (deUint32)imageAccess.getHeight(), // deUint32 bufferImageHeight; 540 { 541 getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect; 542 mipLevelNdx, // deUint32 mipLevel; 543 0u, // deUint32 baseArrayLayer; 544 arraySize, // deUint32 layerCount; 545 }, // VkImageSubresourceLayers imageSubresource; 546 { 0, 0, 0 }, // VkOffset3D imageOffset; 547 copyExtent // VkExtent3D imageExtent; 548 }; 549 550 copyRegions.push_back(copyRegion); 551 } 552 553 // Write buffer data 554 deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize); 555 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize); 556 557 // Copy buffer to image 558 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 559 { 560 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 561 DE_NULL, // const void* pNext; 562 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 563 (const VkCommandBufferInheritanceInfo*)DE_NULL, 564 }; 565 566 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 567 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 568 1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier)); 569 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), ©Regions[0]); 570 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 571 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 572 573 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); 574 } 575 576 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels) 577 { 578 if (tcu::isCombinedDepthStencilType(src.getFormat().type)) 579 { 580 if (tcu::hasDepthComponent(src.getFormat().order)) 581 { 582 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth()); 583 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH)); 584 uploadImageAspect(depthTexture.getAccess(), dst, parms); 585 } 586 587 if (tcu::hasStencilComponent(src.getFormat().order)) 588 { 589 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth()); 590 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL)); 591 uploadImageAspect(stencilTexture.getAccess(), dst, parms); 592 } 593 } 594 else 595 uploadImageAspect(src, dst, parms, mipLevels); 596 } 597 598 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result) 599 { 600 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess(); 601 602 if (isFloatFormat(result.getFormat())) 603 { 604 const tcu::Vec4 threshold (0.0f); 605 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT)) 606 return tcu::TestStatus::fail("CopiesAndBlitting test"); 607 } 608 else 609 { 610 const tcu::UVec4 threshold (0u); 611 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT)) 612 return tcu::TestStatus::fail("CopiesAndBlitting test"); 613 } 614 615 return tcu::TestStatus::pass("CopiesAndBlitting test"); 616 } 617 618 void CopiesAndBlittingTestInstance::generateExpectedResult (void) 619 { 620 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess(); 621 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess(); 622 623 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth())); 624 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst); 625 626 for (deUint32 i = 0; i < m_params.regions.size(); i++) 627 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]); 628 } 629 630 class CopiesAndBlittingTestCase : public vkt::TestCase 631 { 632 public: 633 CopiesAndBlittingTestCase (tcu::TestContext& testCtx, 634 const std::string& name, 635 const std::string& description) 636 : vkt::TestCase (testCtx, name, description) 637 {} 638 639 virtual TestInstance* createInstance (Context& context) const = 0; 640 }; 641 642 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, 643 const tcu::PixelBufferAccess& dst, 644 const ImageParms& imageParms, 645 const deUint32 mipLevel) 646 { 647 const InstanceInterface& vki = m_context.getInstanceInterface(); 648 const DeviceInterface& vk = m_context.getDeviceInterface(); 649 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); 650 const VkDevice device = m_context.getDevice(); 651 const VkQueue queue = m_context.getUniversalQueue(); 652 Allocator& allocator = m_context.getDefaultAllocator(); 653 654 Move<VkBuffer> buffer; 655 de::MovePtr<Allocation> bufferAlloc; 656 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 657 const VkDeviceSize pixelDataSize = calculateSize(dst); 658 659 const VkExtent3D imageExtent = 660 { 661 (deUint32)dst.getWidth(), 662 (deUint32)dst.getHeight(), 663 (imageParms.imageType == VK_IMAGE_TYPE_3D) ? (deUint32)dst.getDepth() : 1, 664 }; 665 666 // Create destination buffer 667 { 668 const VkBufferCreateInfo bufferParams = 669 { 670 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 671 DE_NULL, // const void* pNext; 672 0u, // VkBufferCreateFlags flags; 673 pixelDataSize, // VkDeviceSize size; 674 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 675 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 676 1u, // deUint32 queueFamilyIndexCount; 677 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 678 }; 679 680 buffer = createBuffer(vk, device, &bufferParams); 681 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind); 682 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 683 684 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize)); 685 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); 686 } 687 688 // Barriers for copying image to buffer 689 const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(imageParms.format)); 690 const VkImageMemoryBarrier imageBarrier = 691 { 692 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 693 DE_NULL, // const void* pNext; 694 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 695 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 696 imageParms.operationLayout, // VkImageLayout oldLayout; 697 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 698 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 699 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 700 image, // VkImage image; 701 { // VkImageSubresourceRange subresourceRange; 702 formatAspect, // VkImageAspectFlags aspectMask; 703 mipLevel, // deUint32 baseMipLevel; 704 1u, // deUint32 mipLevels; 705 0u, // deUint32 baseArraySlice; 706 getArraySize(imageParms)// deUint32 arraySize; 707 } 708 }; 709 710 const VkBufferMemoryBarrier bufferBarrier = 711 { 712 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 713 DE_NULL, // const void* pNext; 714 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 715 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 716 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 717 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 718 *buffer, // VkBuffer buffer; 719 0u, // VkDeviceSize offset; 720 pixelDataSize // VkDeviceSize size; 721 }; 722 723 const VkImageMemoryBarrier postImageBarrier = 724 { 725 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 726 DE_NULL, // const void* pNext; 727 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask; 728 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 729 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout; 730 imageParms.operationLayout, // VkImageLayout newLayout; 731 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 732 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 733 image, // VkImage image; 734 { 735 formatAspect, // VkImageAspectFlags aspectMask; 736 mipLevel, // deUint32 baseMipLevel; 737 1u, // deUint32 mipLevels; 738 0u, // deUint32 baseArraySlice; 739 getArraySize(imageParms) // deUint32 arraySize; 740 } // VkImageSubresourceRange subresourceRange; 741 }; 742 743 // Copy image to buffer 744 const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); 745 const VkBufferImageCopy copyRegion = 746 { 747 0u, // VkDeviceSize bufferOffset; 748 (deUint32)dst.getWidth(), // deUint32 bufferRowLength; 749 (deUint32)dst.getHeight(), // deUint32 bufferImageHeight; 750 { 751 aspect, // VkImageAspectFlags aspect; 752 mipLevel, // deUint32 mipLevel; 753 0u, // deUint32 baseArrayLayer; 754 getArraySize(imageParms), // deUint32 layerCount; 755 }, // VkImageSubresourceLayers imageSubresource; 756 { 0, 0, 0 }, // VkOffset3D imageOffset; 757 imageExtent // VkExtent3D imageExtent; 758 }; 759 760 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 761 { 762 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 763 DE_NULL, // const void* pNext; 764 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 765 (const VkCommandBufferInheritanceInfo*)DE_NULL, 766 }; 767 768 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 769 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier); 770 vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); 771 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier); 772 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 773 774 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer); 775 776 // Read buffer data 777 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); 778 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr())); 779 } 780 781 void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer) 782 { 783 const VkSubmitInfo submitInfo = 784 { 785 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 786 DE_NULL, // const void* pNext; 787 0u, // deUint32 waitSemaphoreCount; 788 DE_NULL, // const VkSemaphore* pWaitSemaphores; 789 (const VkPipelineStageFlags*)DE_NULL, 790 1u, // deUint32 commandBufferCount; 791 &cmdBuffer, // const VkCommandBuffer* pCommandBuffers; 792 0u, // deUint32 signalSemaphoreCount; 793 DE_NULL // const VkSemaphore* pSignalSemaphores; 794 }; 795 796 VK_CHECK(vk.resetFences(device, 1, &m_fence.get())); 797 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 798 VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); 799 } 800 801 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage image, 802 const ImageParms& parms, 803 const deUint32 mipLevel) 804 { 805 const tcu::TextureFormat imageFormat = mapVkFormat(parms.format); 806 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth)); 807 808 if (tcu::isCombinedDepthStencilType(imageFormat.type)) 809 { 810 if (tcu::hasDepthComponent(imageFormat.order)) 811 { 812 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth); 813 readImageAspect(image, depthTexture.getAccess(), parms); 814 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess()); 815 } 816 817 if (tcu::hasStencilComponent(imageFormat.order)) 818 { 819 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth); 820 readImageAspect(image, stencilTexture.getAccess(), parms); 821 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess()); 822 } 823 } 824 else 825 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel); 826 827 return resultLevel; 828 } 829 830 // Copy from image to image. 831 832 class CopyImageToImage : public CopiesAndBlittingTestInstance 833 { 834 public: 835 CopyImageToImage (Context& context, 836 TestParams params); 837 virtual tcu::TestStatus iterate (void); 838 839 protected: 840 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess()); 841 842 private: 843 Move<VkImage> m_source; 844 de::MovePtr<Allocation> m_sourceImageAlloc; 845 Move<VkImage> m_destination; 846 de::MovePtr<Allocation> m_destinationImageAlloc; 847 848 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); 849 }; 850 851 CopyImageToImage::CopyImageToImage (Context& context, TestParams params) 852 : CopiesAndBlittingTestInstance(context, params) 853 { 854 const InstanceInterface& vki = context.getInstanceInterface(); 855 const DeviceInterface& vk = context.getDeviceInterface(); 856 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 857 const VkDevice vkDevice = context.getDevice(); 858 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 859 Allocator& memAlloc = context.getDefaultAllocator(); 860 861 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) || 862 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D)) 863 { 864 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1")) 865 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported"); 866 } 867 868 VkImageFormatProperties properties; 869 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 870 m_params.src.image.format, 871 m_params.src.image.imageType, 872 VK_IMAGE_TILING_OPTIMAL, 873 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 874 0, 875 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) || 876 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 877 m_params.dst.image.format, 878 m_params.dst.image.imageType, 879 VK_IMAGE_TILING_OPTIMAL, 880 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 881 0, 882 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 883 { 884 TCU_THROW(NotSupportedError, "Format not supported"); 885 } 886 887 // Create source image 888 { 889 const VkImageCreateInfo sourceImageParams = 890 { 891 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 892 DE_NULL, // const void* pNext; 893 0u, // VkImageCreateFlags flags; 894 m_params.src.image.imageType, // VkImageType imageType; 895 m_params.src.image.format, // VkFormat format; 896 getExtent3D(m_params.src.image), // VkExtent3D extent; 897 1u, // deUint32 mipLevels; 898 getArraySize(m_params.src.image), // deUint32 arraySize; 899 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 900 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 901 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 902 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 903 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 904 1u, // deUint32 queueFamilyCount; 905 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 906 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 907 }; 908 909 m_source = createImage(vk, vkDevice, &sourceImageParams); 910 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 911 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); 912 } 913 914 // Create destination image 915 { 916 const VkImageCreateInfo destinationImageParams = 917 { 918 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 919 DE_NULL, // const void* pNext; 920 0u, // VkImageCreateFlags flags; 921 m_params.dst.image.imageType, // VkImageType imageType; 922 m_params.dst.image.format, // VkFormat format; 923 getExtent3D(m_params.dst.image), // VkExtent3D extent; 924 1u, // deUint32 mipLevels; 925 getArraySize(m_params.dst.image), // deUint32 arraySize; 926 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 927 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 928 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 929 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 930 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 931 1u, // deUint32 queueFamilyCount; 932 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 933 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 934 }; 935 936 m_destination = createImage(vk, vkDevice, &destinationImageParams); 937 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 938 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); 939 } 940 } 941 942 tcu::TestStatus CopyImageToImage::iterate (void) 943 { 944 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); 945 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); 946 947 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, 948 (int)m_params.src.image.extent.width, 949 (int)m_params.src.image.extent.height, 950 (int)m_params.src.image.extent.depth)); 951 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED); 952 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, 953 (int)m_params.dst.image.extent.width, 954 (int)m_params.dst.image.extent.height, 955 (int)m_params.dst.image.extent.depth)); 956 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_GRADIENT); 957 generateExpectedResult(); 958 959 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image); 960 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image); 961 962 const DeviceInterface& vk = m_context.getDeviceInterface(); 963 const VkDevice vkDevice = m_context.getDevice(); 964 const VkQueue queue = m_context.getUniversalQueue(); 965 966 std::vector<VkImageCopy> imageCopies; 967 for (deUint32 i = 0; i < m_params.regions.size(); i++) 968 { 969 const VkImageCopy& ic = m_params.regions[i].imageCopy; 970 imageCopies.push_back(ic); 971 } 972 973 const VkImageMemoryBarrier imageBarriers[] = 974 { 975 // source image 976 { 977 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 978 DE_NULL, // const void* pNext; 979 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 980 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 981 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 982 m_params.src.image.operationLayout, // VkImageLayout newLayout; 983 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 984 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 985 m_source.get(), // VkImage image; 986 { // VkImageSubresourceRange subresourceRange; 987 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 988 0u, // deUint32 baseMipLevel; 989 1u, // deUint32 mipLevels; 990 0u, // deUint32 baseArraySlice; 991 getArraySize(m_params.src.image)// deUint32 arraySize; 992 } 993 }, 994 // destination image 995 { 996 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 997 DE_NULL, // const void* pNext; 998 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 999 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1000 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1001 m_params.dst.image.operationLayout, // VkImageLayout newLayout; 1002 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1003 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1004 m_destination.get(), // VkImage image; 1005 { // VkImageSubresourceRange subresourceRange; 1006 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 1007 0u, // deUint32 baseMipLevel; 1008 1u, // deUint32 mipLevels; 1009 0u, // deUint32 baseArraySlice; 1010 getArraySize(m_params.dst.image)// deUint32 arraySize; 1011 } 1012 }, 1013 }; 1014 1015 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1016 { 1017 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1018 DE_NULL, // const void* pNext; 1019 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1020 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1021 }; 1022 1023 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1024 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers); 1025 vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data()); 1026 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1027 1028 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); 1029 1030 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image); 1031 1032 return checkTestResult(resultTextureLevel->getAccess()); 1033 } 1034 1035 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result) 1036 { 1037 const tcu::Vec4 fThreshold (0.0f); 1038 const tcu::UVec4 uThreshold (0u); 1039 1040 if (tcu::isCombinedDepthStencilType(result.getFormat().type)) 1041 { 1042 if (tcu::hasDepthComponent(result.getFormat().order)) 1043 { 1044 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; 1045 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); 1046 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode); 1047 1048 if (isFloatFormat(result.getFormat())) 1049 { 1050 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT)) 1051 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1052 } 1053 else 1054 { 1055 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT)) 1056 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1057 } 1058 } 1059 1060 if (tcu::hasStencilComponent(result.getFormat().order)) 1061 { 1062 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; 1063 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); 1064 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode); 1065 1066 if (isFloatFormat(result.getFormat())) 1067 { 1068 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT)) 1069 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1070 } 1071 else 1072 { 1073 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT)) 1074 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1075 } 1076 } 1077 } 1078 else 1079 { 1080 if (isFloatFormat(result.getFormat())) 1081 { 1082 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT)) 1083 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1084 } 1085 else if (isSnormFormat(mapTextureFormat(result.getFormat()))) 1086 { 1087 // There may be an ambiguity between two possible binary representations of 1.0. 1088 // Get rid of that by expanding the data to floats and re-normalizing again. 1089 1090 tcu::TextureLevel resultSnorm (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth()); 1091 { 1092 tcu::TextureLevel resultFloat (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth()); 1093 1094 tcu::copy(resultFloat.getAccess(), result); 1095 tcu::copy(resultSnorm, resultFloat.getAccess()); 1096 } 1097 1098 tcu::TextureLevel expectedSnorm (m_expectedTextureLevel[0]->getFormat(), m_expectedTextureLevel[0]->getWidth(), m_expectedTextureLevel[0]->getHeight(), m_expectedTextureLevel[0]->getDepth()); 1099 1100 { 1101 tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth()); 1102 1103 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess()); 1104 tcu::copy(expectedSnorm, expectedFloat.getAccess()); 1105 } 1106 1107 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT)) 1108 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1109 } 1110 else 1111 { 1112 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT)) 1113 return tcu::TestStatus::fail("CopiesAndBlitting test"); 1114 } 1115 } 1116 1117 return tcu::TestStatus::pass("CopiesAndBlitting test"); 1118 } 1119 1120 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 1121 { 1122 VkOffset3D srcOffset = region.imageCopy.srcOffset; 1123 VkOffset3D dstOffset = region.imageCopy.dstOffset; 1124 VkExtent3D extent = region.imageCopy.extent; 1125 1126 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D) 1127 { 1128 dstOffset.z = srcOffset.z; 1129 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount); 1130 } 1131 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D) 1132 { 1133 srcOffset.z = dstOffset.z; 1134 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount); 1135 } 1136 1137 1138 if (tcu::isCombinedDepthStencilType(src.getFormat().type)) 1139 { 1140 DE_ASSERT(src.getFormat() == dst.getFormat()); 1141 1142 // Copy depth. 1143 if (tcu::hasDepthComponent(src.getFormat().order)) 1144 { 1145 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH); 1146 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH); 1147 tcu::copy(dstSubRegion, srcSubRegion); 1148 } 1149 1150 // Copy stencil. 1151 if (tcu::hasStencilComponent(src.getFormat().order)) 1152 { 1153 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL); 1154 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL); 1155 tcu::copy(dstSubRegion, srcSubRegion); 1156 } 1157 } 1158 else 1159 { 1160 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth); 1161 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy. 1162 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr()); 1163 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth); 1164 1165 tcu::copy(dstSubRegion, srcSubRegion); 1166 } 1167 } 1168 1169 class CopyImageToImageTestCase : public vkt::TestCase 1170 { 1171 public: 1172 CopyImageToImageTestCase (tcu::TestContext& testCtx, 1173 const std::string& name, 1174 const std::string& description, 1175 const TestParams params) 1176 : vkt::TestCase (testCtx, name, description) 1177 , m_params (params) 1178 {} 1179 1180 virtual TestInstance* createInstance (Context& context) const 1181 { 1182 return new CopyImageToImage(context, m_params); 1183 } 1184 private: 1185 TestParams m_params; 1186 }; 1187 1188 // Copy from buffer to buffer. 1189 1190 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance 1191 { 1192 public: 1193 CopyBufferToBuffer (Context& context, TestParams params); 1194 virtual tcu::TestStatus iterate (void); 1195 private: 1196 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion); 1197 Move<VkBuffer> m_source; 1198 de::MovePtr<Allocation> m_sourceBufferAlloc; 1199 Move<VkBuffer> m_destination; 1200 de::MovePtr<Allocation> m_destinationBufferAlloc; 1201 }; 1202 1203 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params) 1204 : CopiesAndBlittingTestInstance (context, params) 1205 { 1206 const InstanceInterface& vki = context.getInstanceInterface(); 1207 const DeviceInterface& vk = context.getDeviceInterface(); 1208 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 1209 const VkDevice vkDevice = context.getDevice(); 1210 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1211 Allocator& memAlloc = context.getDefaultAllocator(); 1212 1213 // Create source buffer 1214 { 1215 const VkBufferCreateInfo sourceBufferParams = 1216 { 1217 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1218 DE_NULL, // const void* pNext; 1219 0u, // VkBufferCreateFlags flags; 1220 m_params.src.buffer.size, // VkDeviceSize size; 1221 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1222 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1223 1u, // deUint32 queueFamilyIndexCount; 1224 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1225 }; 1226 1227 m_source = createBuffer(vk, vkDevice, &sourceBufferParams); 1228 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); 1229 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset())); 1230 } 1231 1232 // Create destination buffer 1233 { 1234 const VkBufferCreateInfo destinationBufferParams = 1235 { 1236 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1237 DE_NULL, // const void* pNext; 1238 0u, // VkBufferCreateFlags flags; 1239 m_params.dst.buffer.size, // VkDeviceSize size; 1240 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1241 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1242 1u, // deUint32 queueFamilyIndexCount; 1243 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1244 }; 1245 1246 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams); 1247 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); 1248 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset())); 1249 } 1250 } 1251 1252 tcu::TestStatus CopyBufferToBuffer::iterate (void) 1253 { 1254 const int srcLevelWidth = (int)(m_params.src.buffer.size/4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4 1255 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1)); 1256 generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED); 1257 1258 const int dstLevelWidth = (int)(m_params.dst.buffer.size/4); 1259 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1)); 1260 generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE); 1261 1262 generateExpectedResult(); 1263 1264 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc); 1265 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc); 1266 1267 const DeviceInterface& vk = m_context.getDeviceInterface(); 1268 const VkDevice vkDevice = m_context.getDevice(); 1269 const VkQueue queue = m_context.getUniversalQueue(); 1270 1271 const VkBufferMemoryBarrier srcBufferBarrier = 1272 { 1273 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1274 DE_NULL, // const void* pNext; 1275 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 1276 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1277 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1278 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1279 *m_source, // VkBuffer buffer; 1280 0u, // VkDeviceSize offset; 1281 m_params.src.buffer.size // VkDeviceSize size; 1282 }; 1283 1284 const VkBufferMemoryBarrier dstBufferBarrier = 1285 { 1286 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1287 DE_NULL, // const void* pNext; 1288 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1289 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1290 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1291 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1292 *m_destination, // VkBuffer buffer; 1293 0u, // VkDeviceSize offset; 1294 m_params.dst.buffer.size // VkDeviceSize size; 1295 }; 1296 1297 std::vector<VkBufferCopy> bufferCopies; 1298 for (deUint32 i = 0; i < m_params.regions.size(); i++) 1299 bufferCopies.push_back(m_params.regions[i].bufferCopy); 1300 1301 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1302 { 1303 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1304 DE_NULL, // const void* pNext; 1305 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1306 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1307 }; 1308 1309 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1310 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1311 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]); 1312 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1313 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1314 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); 1315 1316 1317 1318 // Read buffer data 1319 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1)); 1320 invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size); 1321 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr())); 1322 1323 return checkTestResult(resultLevel->getAccess()); 1324 } 1325 1326 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 1327 { 1328 deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset, 1329 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset, 1330 (size_t)region.bufferCopy.size); 1331 } 1332 1333 class BufferToBufferTestCase : public vkt::TestCase 1334 { 1335 public: 1336 BufferToBufferTestCase (tcu::TestContext& testCtx, 1337 const std::string& name, 1338 const std::string& description, 1339 const TestParams params) 1340 : vkt::TestCase (testCtx, name, description) 1341 , m_params (params) 1342 {} 1343 1344 virtual TestInstance* createInstance (Context& context) const 1345 { 1346 return new CopyBufferToBuffer(context, m_params); 1347 } 1348 private: 1349 TestParams m_params; 1350 }; 1351 1352 // Copy from image to buffer. 1353 1354 class CopyImageToBuffer : public CopiesAndBlittingTestInstance 1355 { 1356 public: 1357 CopyImageToBuffer (Context& context, 1358 TestParams testParams); 1359 virtual tcu::TestStatus iterate (void); 1360 private: 1361 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); 1362 1363 tcu::TextureFormat m_textureFormat; 1364 VkDeviceSize m_bufferSize; 1365 1366 Move<VkImage> m_source; 1367 de::MovePtr<Allocation> m_sourceImageAlloc; 1368 Move<VkBuffer> m_destination; 1369 de::MovePtr<Allocation> m_destinationBufferAlloc; 1370 }; 1371 1372 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams) 1373 : CopiesAndBlittingTestInstance(context, testParams) 1374 , m_textureFormat(mapVkFormat(testParams.src.image.format)) 1375 , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat)) 1376 { 1377 const InstanceInterface& vki = context.getInstanceInterface(); 1378 const DeviceInterface& vk = context.getDeviceInterface(); 1379 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 1380 const VkDevice vkDevice = context.getDevice(); 1381 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1382 Allocator& memAlloc = context.getDefaultAllocator(); 1383 1384 // Create source image 1385 { 1386 const VkImageCreateInfo sourceImageParams = 1387 { 1388 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1389 DE_NULL, // const void* pNext; 1390 0u, // VkImageCreateFlags flags; 1391 m_params.src.image.imageType, // VkImageType imageType; 1392 m_params.src.image.format, // VkFormat format; 1393 getExtent3D(m_params.src.image), // VkExtent3D extent; 1394 1u, // deUint32 mipLevels; 1395 getArraySize(m_params.src.image), // deUint32 arraySize; 1396 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1397 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1398 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1399 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 1400 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1401 1u, // deUint32 queueFamilyCount; 1402 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1403 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1404 }; 1405 1406 m_source = createImage(vk, vkDevice, &sourceImageParams); 1407 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 1408 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); 1409 } 1410 1411 // Create destination buffer 1412 { 1413 const VkBufferCreateInfo destinationBufferParams = 1414 { 1415 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1416 DE_NULL, // const void* pNext; 1417 0u, // VkBufferCreateFlags flags; 1418 m_bufferSize, // VkDeviceSize size; 1419 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 1420 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1421 1u, // deUint32 queueFamilyIndexCount; 1422 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1423 }; 1424 1425 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams); 1426 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); 1427 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset())); 1428 } 1429 } 1430 1431 tcu::TestStatus CopyImageToBuffer::iterate (void) 1432 { 1433 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, 1434 m_params.src.image.extent.width, 1435 m_params.src.image.extent.height, 1436 m_params.src.image.extent.depth)); 1437 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth); 1438 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1)); 1439 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1); 1440 1441 generateExpectedResult(); 1442 1443 uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image); 1444 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc); 1445 1446 const DeviceInterface& vk = m_context.getDeviceInterface(); 1447 const VkDevice vkDevice = m_context.getDevice(); 1448 const VkQueue queue = m_context.getUniversalQueue(); 1449 1450 // Barriers for copying image to buffer 1451 const VkImageMemoryBarrier imageBarrier = 1452 { 1453 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1454 DE_NULL, // const void* pNext; 1455 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1456 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1457 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1458 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 1459 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1460 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1461 *m_source, // VkImage image; 1462 { // VkImageSubresourceRange subresourceRange; 1463 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask; 1464 0u, // deUint32 baseMipLevel; 1465 1u, // deUint32 mipLevels; 1466 0u, // deUint32 baseArraySlice; 1467 1u // deUint32 arraySize; 1468 } 1469 }; 1470 1471 const VkBufferMemoryBarrier bufferBarrier = 1472 { 1473 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 1474 DE_NULL, // const void* pNext; 1475 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1476 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 1477 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1478 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1479 *m_destination, // VkBuffer buffer; 1480 0u, // VkDeviceSize offset; 1481 m_bufferSize // VkDeviceSize size; 1482 }; 1483 1484 // Copy from image to buffer 1485 std::vector<VkBufferImageCopy> bufferImageCopies; 1486 for (deUint32 i = 0; i < m_params.regions.size(); i++) 1487 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy); 1488 1489 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1490 { 1491 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1492 DE_NULL, // const void* pNext; 1493 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1494 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1495 }; 1496 1497 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1498 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier); 1499 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]); 1500 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); 1501 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1502 1503 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); 1504 1505 // Read buffer data 1506 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1)); 1507 invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize); 1508 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr())); 1509 1510 return checkTestResult(resultLevel->getAccess()); 1511 } 1512 1513 class CopyImageToBufferTestCase : public vkt::TestCase 1514 { 1515 public: 1516 CopyImageToBufferTestCase (tcu::TestContext& testCtx, 1517 const std::string& name, 1518 const std::string& description, 1519 const TestParams params) 1520 : vkt::TestCase (testCtx, name, description) 1521 , m_params (params) 1522 {} 1523 1524 virtual TestInstance* createInstance (Context& context) const 1525 { 1526 return new CopyImageToBuffer(context, m_params); 1527 } 1528 private: 1529 TestParams m_params; 1530 }; 1531 1532 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 1533 { 1534 deUint32 rowLength = region.bufferImageCopy.bufferRowLength; 1535 if (!rowLength) 1536 rowLength = region.bufferImageCopy.imageExtent.width; 1537 1538 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight; 1539 if (!imageHeight) 1540 imageHeight = region.bufferImageCopy.imageExtent.height; 1541 1542 const int texelSize = src.getFormat().getPixelSize(); 1543 const VkExtent3D extent = region.bufferImageCopy.imageExtent; 1544 const VkOffset3D srcOffset = region.bufferImageCopy.imageOffset; 1545 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize; 1546 1547 for (deUint32 z = 0; z < extent.depth; z++) 1548 { 1549 for (deUint32 y = 0; y < extent.height; y++) 1550 { 1551 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength; 1552 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z, 1553 region.bufferImageCopy.imageExtent.width, 1, 1); 1554 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1); 1555 tcu::copy(dstSubRegion, srcSubRegion); 1556 } 1557 } 1558 } 1559 1560 // Copy from buffer to image. 1561 1562 class CopyBufferToImage : public CopiesAndBlittingTestInstance 1563 { 1564 public: 1565 CopyBufferToImage (Context& context, 1566 TestParams testParams); 1567 virtual tcu::TestStatus iterate (void); 1568 private: 1569 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); 1570 1571 tcu::TextureFormat m_textureFormat; 1572 VkDeviceSize m_bufferSize; 1573 1574 Move<VkBuffer> m_source; 1575 de::MovePtr<Allocation> m_sourceBufferAlloc; 1576 Move<VkImage> m_destination; 1577 de::MovePtr<Allocation> m_destinationImageAlloc; 1578 }; 1579 1580 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams) 1581 : CopiesAndBlittingTestInstance(context, testParams) 1582 , m_textureFormat(mapVkFormat(testParams.dst.image.format)) 1583 , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat)) 1584 { 1585 const InstanceInterface& vki = context.getInstanceInterface(); 1586 const DeviceInterface& vk = context.getDeviceInterface(); 1587 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 1588 const VkDevice vkDevice = context.getDevice(); 1589 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1590 Allocator& memAlloc = context.getDefaultAllocator(); 1591 1592 // Create source buffer 1593 { 1594 const VkBufferCreateInfo sourceBufferParams = 1595 { 1596 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 1597 DE_NULL, // const void* pNext; 1598 0u, // VkBufferCreateFlags flags; 1599 m_bufferSize, // VkDeviceSize size; 1600 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 1601 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1602 1u, // deUint32 queueFamilyIndexCount; 1603 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1604 }; 1605 1606 m_source = createBuffer(vk, vkDevice, &sourceBufferParams); 1607 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); 1608 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset())); 1609 } 1610 1611 // Create destination image 1612 { 1613 const VkImageCreateInfo destinationImageParams = 1614 { 1615 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1616 DE_NULL, // const void* pNext; 1617 0u, // VkImageCreateFlags flags; 1618 m_params.dst.image.imageType, // VkImageType imageType; 1619 m_params.dst.image.format, // VkFormat format; 1620 getExtent3D(m_params.dst.image), // VkExtent3D extent; 1621 1u, // deUint32 mipLevels; 1622 getArraySize(m_params.dst.image), // deUint32 arraySize; 1623 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1624 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1625 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1626 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 1627 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1628 1u, // deUint32 queueFamilyCount; 1629 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1630 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1631 }; 1632 1633 m_destination = createImage(vk, vkDevice, &destinationImageParams); 1634 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 1635 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); 1636 } 1637 } 1638 1639 tcu::TestStatus CopyBufferToImage::iterate (void) 1640 { 1641 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1)); 1642 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1); 1643 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, 1644 m_params.dst.image.extent.width, 1645 m_params.dst.image.extent.height, 1646 m_params.dst.image.extent.depth)); 1647 1648 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth); 1649 1650 generateExpectedResult(); 1651 1652 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc); 1653 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image); 1654 1655 const DeviceInterface& vk = m_context.getDeviceInterface(); 1656 const VkDevice vkDevice = m_context.getDevice(); 1657 const VkQueue queue = m_context.getUniversalQueue(); 1658 1659 const VkImageMemoryBarrier imageBarrier = 1660 { 1661 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1662 DE_NULL, // const void* pNext; 1663 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1664 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1665 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1666 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 1667 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1668 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1669 *m_destination, // VkImage image; 1670 { // VkImageSubresourceRange subresourceRange; 1671 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask; 1672 0u, // deUint32 baseMipLevel; 1673 1u, // deUint32 mipLevels; 1674 0u, // deUint32 baseArraySlice; 1675 1u // deUint32 arraySize; 1676 } 1677 }; 1678 1679 // Copy from buffer to image 1680 std::vector<VkBufferImageCopy> bufferImageCopies; 1681 for (deUint32 i = 0; i < m_params.regions.size(); i++) 1682 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy); 1683 1684 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1685 { 1686 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1687 DE_NULL, // const void* pNext; 1688 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1689 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1690 }; 1691 1692 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1693 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier); 1694 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data()); 1695 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1696 1697 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); 1698 1699 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image); 1700 1701 return checkTestResult(resultLevel->getAccess()); 1702 } 1703 1704 class CopyBufferToImageTestCase : public vkt::TestCase 1705 { 1706 public: 1707 CopyBufferToImageTestCase (tcu::TestContext& testCtx, 1708 const std::string& name, 1709 const std::string& description, 1710 const TestParams params) 1711 : vkt::TestCase (testCtx, name, description) 1712 , m_params (params) 1713 {} 1714 1715 virtual ~CopyBufferToImageTestCase (void) {} 1716 1717 virtual TestInstance* createInstance (Context& context) const 1718 { 1719 return new CopyBufferToImage(context, m_params); 1720 } 1721 private: 1722 TestParams m_params; 1723 }; 1724 1725 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 1726 { 1727 deUint32 rowLength = region.bufferImageCopy.bufferRowLength; 1728 if (!rowLength) 1729 rowLength = region.bufferImageCopy.imageExtent.width; 1730 1731 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight; 1732 if (!imageHeight) 1733 imageHeight = region.bufferImageCopy.imageExtent.height; 1734 1735 const int texelSize = dst.getFormat().getPixelSize(); 1736 const VkExtent3D extent = region.bufferImageCopy.imageExtent; 1737 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset; 1738 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize; 1739 1740 for (deUint32 z = 0; z < extent.depth; z++) 1741 { 1742 for (deUint32 y = 0; y < extent.height; y++) 1743 { 1744 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength; 1745 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1); 1746 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z, 1747 region.bufferImageCopy.imageExtent.width, 1, 1); 1748 tcu::copy(dstSubRegion, srcSubRegion); 1749 } 1750 } 1751 } 1752 1753 // Copy from image to image with scaling. 1754 1755 class BlittingImages : public CopiesAndBlittingTestInstance 1756 { 1757 public: 1758 BlittingImages (Context& context, 1759 TestParams params); 1760 virtual tcu::TestStatus iterate (void); 1761 protected: 1762 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result); 1763 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); 1764 virtual void generateExpectedResult (void); 1765 private: 1766 bool checkLinearFilteredResult (const tcu::ConstPixelBufferAccess& result, 1767 const tcu::ConstPixelBufferAccess& clampedReference, 1768 const tcu::ConstPixelBufferAccess& unclampedReference, 1769 const tcu::TextureFormat& sourceFormat); 1770 bool checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result, 1771 const tcu::ConstPixelBufferAccess& source); 1772 1773 Move<VkImage> m_source; 1774 de::MovePtr<Allocation> m_sourceImageAlloc; 1775 Move<VkImage> m_destination; 1776 de::MovePtr<Allocation> m_destinationImageAlloc; 1777 1778 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel; 1779 }; 1780 1781 BlittingImages::BlittingImages (Context& context, TestParams params) 1782 : CopiesAndBlittingTestInstance(context, params) 1783 { 1784 const InstanceInterface& vki = context.getInstanceInterface(); 1785 const DeviceInterface& vk = context.getDeviceInterface(); 1786 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 1787 const VkDevice vkDevice = context.getDevice(); 1788 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1789 Allocator& memAlloc = context.getDefaultAllocator(); 1790 1791 VkImageFormatProperties properties; 1792 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 1793 m_params.src.image.format, 1794 VK_IMAGE_TYPE_2D, 1795 VK_IMAGE_TILING_OPTIMAL, 1796 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 1797 0, 1798 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) || 1799 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 1800 m_params.dst.image.format, 1801 VK_IMAGE_TYPE_2D, 1802 VK_IMAGE_TILING_OPTIMAL, 1803 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1804 0, 1805 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 1806 { 1807 TCU_THROW(NotSupportedError, "Format not supported"); 1808 } 1809 1810 VkFormatProperties srcFormatProperties; 1811 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties); 1812 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT)) 1813 { 1814 TCU_THROW(NotSupportedError, "Format feature blit source not supported"); 1815 } 1816 1817 VkFormatProperties dstFormatProperties; 1818 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties); 1819 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT)) 1820 { 1821 TCU_THROW(NotSupportedError, "Format feature blit destination not supported"); 1822 } 1823 1824 if (m_params.filter == VK_FILTER_LINEAR) 1825 { 1826 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) 1827 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported"); 1828 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) 1829 TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported"); 1830 } 1831 1832 // Create source image 1833 { 1834 const VkImageCreateInfo sourceImageParams = 1835 { 1836 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1837 DE_NULL, // const void* pNext; 1838 0u, // VkImageCreateFlags flags; 1839 m_params.src.image.imageType, // VkImageType imageType; 1840 m_params.src.image.format, // VkFormat format; 1841 getExtent3D(m_params.src.image), // VkExtent3D extent; 1842 1u, // deUint32 mipLevels; 1843 getArraySize(m_params.src.image), // deUint32 arraySize; 1844 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1845 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1846 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1847 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 1848 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1849 1u, // deUint32 queueFamilyCount; 1850 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1851 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1852 }; 1853 1854 m_source = createImage(vk, vkDevice, &sourceImageParams); 1855 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 1856 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); 1857 } 1858 1859 // Create destination image 1860 { 1861 const VkImageCreateInfo destinationImageParams = 1862 { 1863 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1864 DE_NULL, // const void* pNext; 1865 0u, // VkImageCreateFlags flags; 1866 m_params.dst.image.imageType, // VkImageType imageType; 1867 m_params.dst.image.format, // VkFormat format; 1868 getExtent3D(m_params.dst.image), // VkExtent3D extent; 1869 1u, // deUint32 mipLevels; 1870 getArraySize(m_params.dst.image), // deUint32 arraySize; 1871 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 1872 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1873 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1874 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 1875 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1876 1u, // deUint32 queueFamilyCount; 1877 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 1878 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1879 }; 1880 1881 m_destination = createImage(vk, vkDevice, &destinationImageParams); 1882 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 1883 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); 1884 } 1885 } 1886 1887 tcu::TestStatus BlittingImages::iterate (void) 1888 { 1889 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); 1890 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); 1891 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, 1892 m_params.src.image.extent.width, 1893 m_params.src.image.extent.height, 1894 m_params.src.image.extent.depth)); 1895 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT); 1896 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, 1897 (int)m_params.dst.image.extent.width, 1898 (int)m_params.dst.image.extent.height, 1899 (int)m_params.dst.image.extent.depth)); 1900 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE); 1901 generateExpectedResult(); 1902 1903 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image); 1904 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image); 1905 1906 const DeviceInterface& vk = m_context.getDeviceInterface(); 1907 const VkDevice vkDevice = m_context.getDevice(); 1908 const VkQueue queue = m_context.getUniversalQueue(); 1909 1910 std::vector<VkImageBlit> regions; 1911 for (deUint32 i = 0; i < m_params.regions.size(); i++) 1912 regions.push_back(m_params.regions[i].imageBlit); 1913 1914 // Barriers for copying image to buffer 1915 const VkImageMemoryBarrier srcImageBarrier = 1916 { 1917 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1918 DE_NULL, // const void* pNext; 1919 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1920 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 1921 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1922 m_params.src.image.operationLayout, // VkImageLayout newLayout; 1923 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1924 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1925 m_source.get(), // VkImage image; 1926 { // VkImageSubresourceRange subresourceRange; 1927 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 1928 0u, // deUint32 baseMipLevel; 1929 1u, // deUint32 mipLevels; 1930 0u, // deUint32 baseArraySlice; 1931 1u // deUint32 arraySize; 1932 } 1933 }; 1934 1935 const VkImageMemoryBarrier dstImageBarrier = 1936 { 1937 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 1938 DE_NULL, // const void* pNext; 1939 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 1940 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 1941 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 1942 m_params.dst.image.operationLayout, // VkImageLayout newLayout; 1943 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 1944 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 1945 m_destination.get(), // VkImage image; 1946 { // VkImageSubresourceRange subresourceRange; 1947 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 1948 0u, // deUint32 baseMipLevel; 1949 1u, // deUint32 mipLevels; 1950 0u, // deUint32 baseArraySlice; 1951 1u // deUint32 arraySize; 1952 } 1953 }; 1954 1955 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 1956 { 1957 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 1958 DE_NULL, // const void* pNext; 1959 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 1960 (const VkCommandBufferInheritanceInfo*)DE_NULL, 1961 }; 1962 1963 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 1964 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier); 1965 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier); 1966 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter); 1967 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 1968 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); 1969 1970 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image); 1971 1972 return checkTestResult(resultTextureLevel->getAccess()); 1973 } 1974 1975 static float calculateFloatConversionError (int srcBits) 1976 { 1977 if (srcBits > 0) 1978 { 1979 const int clampedBits = de::clamp<int>(srcBits, 0, 32); 1980 const float srcMaxValue = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f); 1981 const float error = 1.0f / srcMaxValue; 1982 1983 return de::clamp<float>(error, 0.0f, 1.0f); 1984 } 1985 else 1986 return 1.0f; 1987 } 1988 1989 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format) 1990 { 1991 tcu::Vec4 threshold(0.01f); 1992 1993 switch (format.type) 1994 { 1995 case tcu::TextureFormat::HALF_FLOAT: 1996 threshold = tcu::Vec4(0.005f); 1997 break; 1998 1999 case tcu::TextureFormat::FLOAT: 2000 case tcu::TextureFormat::FLOAT64: 2001 threshold = tcu::Vec4(0.001f); 2002 break; 2003 2004 case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: 2005 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f); 2006 break; 2007 2008 case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV: 2009 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f); 2010 break; 2011 2012 default: 2013 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format); 2014 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()), 2015 calculateFloatConversionError(bits.y()), 2016 calculateFloatConversionError(bits.z()), 2017 calculateFloatConversionError(bits.w())); 2018 } 2019 2020 // Return value matching the channel order specified by the format 2021 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA) 2022 return threshold.swizzle(2, 1, 0, 3); 2023 else 2024 return threshold; 2025 } 2026 2027 bool BlittingImages::checkLinearFilteredResult (const tcu::ConstPixelBufferAccess& result, 2028 const tcu::ConstPixelBufferAccess& clampedExpected, 2029 const tcu::ConstPixelBufferAccess& unclampedExpected, 2030 const tcu::TextureFormat& srcFormat) 2031 { 2032 tcu::TestLog& log (m_context.getTestContext().getLog()); 2033 const tcu::TextureFormat dstFormat = result.getFormat(); 2034 bool isOk = false; 2035 2036 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image."); 2037 2038 if (isFloatFormat(dstFormat)) 2039 { 2040 const bool srcIsSRGB = tcu::isSRGB(srcFormat); 2041 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f); 2042 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat); 2043 const tcu::Vec4 threshold = tcu::max(srcMaxDiff, dstMaxDiff); 2044 2045 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); 2046 log << tcu::TestLog::EndSection; 2047 2048 if (!isOk) 2049 { 2050 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image."); 2051 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); 2052 log << tcu::TestLog::EndSection; 2053 } 2054 } 2055 else 2056 { 2057 tcu::UVec4 threshold; 2058 // Calculate threshold depending on channel width of destination format. 2059 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(dstFormat); 2060 for (deUint32 i = 0; i < 4; ++i) 2061 threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1); 2062 2063 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); 2064 log << tcu::TestLog::EndSection; 2065 2066 if (!isOk) 2067 { 2068 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image."); 2069 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); 2070 log << tcu::TestLog::EndSection; 2071 } 2072 } 2073 2074 return isOk; 2075 } 2076 2077 //! Utility to encapsulate coordinate computation and loops. 2078 struct CompareEachPixelInEachRegion 2079 { 2080 virtual ~CompareEachPixelInEachRegion (void) {} 2081 virtual bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const = 0; 2082 2083 bool forEach (const void* pUserData, 2084 const std::vector<CopyRegion>& regions, 2085 const int sourceWidth, 2086 const int sourceHeight, 2087 const tcu::PixelBufferAccess& errorMask) const 2088 { 2089 bool compareOk = true; 2090 2091 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter) 2092 { 2093 const VkImageBlit& blit = regionIter->imageBlit; 2094 2095 const int dx = deSign32(blit.dstOffsets[1].x - blit.dstOffsets[0].x); 2096 const int dy = deSign32(blit.dstOffsets[1].y - blit.dstOffsets[0].y); 2097 const float xScale = static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x); 2098 const float yScale = static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y); 2099 const float srcInvW = 1.0f / static_cast<float>(sourceWidth); 2100 const float srcInvH = 1.0f / static_cast<float>(sourceHeight); 2101 2102 for (int y = blit.dstOffsets[0].y; y < blit.dstOffsets[1].y; y += dy) 2103 for (int x = blit.dstOffsets[0].x; x < blit.dstOffsets[1].x; x += dx) 2104 { 2105 const tcu::Vec2 srcNormCoord 2106 ( 2107 (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW, 2108 (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH 2109 ); 2110 2111 if (!compare(pUserData, x, y, srcNormCoord)) 2112 { 2113 errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y); 2114 compareOk = false; 2115 } 2116 } 2117 } 2118 return compareOk; 2119 } 2120 }; 2121 2122 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format) 2123 { 2124 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); 2125 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format); 2126 2127 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) 2128 { 2129 return getFormatThreshold(format); 2130 } 2131 else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT || 2132 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) 2133 { 2134 const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT); 2135 const float range = isSigned ? 1.0f - (-1.0f) 2136 : 1.0f - 0.0f; 2137 2138 tcu::Vec4 v; 2139 for (int i = 0; i < 4; ++i) 2140 { 2141 if (bitDepth[i] == 0) 2142 v[i] = 1.0f; 2143 else 2144 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1); 2145 } 2146 return v; 2147 } 2148 else 2149 { 2150 DE_ASSERT(0); 2151 return tcu::Vec4(); 2152 } 2153 } 2154 2155 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess& source, 2156 const tcu::ConstPixelBufferAccess& result, 2157 const tcu::PixelBufferAccess& errorMask, 2158 const std::vector<CopyRegion>& regions) 2159 { 2160 const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST); 2161 tcu::LookupPrecision precision; 2162 2163 { 2164 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat()); 2165 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat()); 2166 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat()); 2167 2168 precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0)); 2169 precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff); 2170 } 2171 2172 const struct Capture 2173 { 2174 const tcu::ConstPixelBufferAccess& source; 2175 const tcu::ConstPixelBufferAccess& result; 2176 const tcu::Sampler& sampler; 2177 const tcu::LookupPrecision& precision; 2178 const bool isSRGB; 2179 } capture = 2180 { 2181 source, result, sampler, precision, tcu::isSRGB(result.getFormat()) 2182 }; 2183 2184 const struct Loop : CompareEachPixelInEachRegion 2185 { 2186 Loop (void) {} 2187 2188 bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const 2189 { 2190 const Capture& c = *static_cast<const Capture*>(pUserData); 2191 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY; 2192 tcu::Vec4 dstColor = c.result.getPixel(x, y); 2193 2194 // TexLookupVerifier performs a conversion to linear space, so we have to as well 2195 if (c.isSRGB) 2196 dstColor = tcu::sRGBToLinear(dstColor); 2197 2198 return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor); 2199 } 2200 } loop; 2201 2202 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask); 2203 } 2204 2205 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source, 2206 const tcu::ConstPixelBufferAccess& result, 2207 const tcu::PixelBufferAccess& errorMask, 2208 const std::vector<CopyRegion>& regions) 2209 { 2210 const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST); 2211 tcu::IntLookupPrecision precision; 2212 2213 { 2214 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat()); 2215 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat()); 2216 2217 for (deUint32 i = 0; i < 4; ++i) { 2218 precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1); 2219 precision.colorMask[i] = dstBitDepth[i] != 0; 2220 } 2221 } 2222 2223 // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that 2224 // does the conversion on the fly without wasting memory, but this approach is more straightforward. 2225 tcu::TextureLevel convertedSourceTexture (result.getFormat(), source.getWidth(), source.getHeight()); 2226 const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess(); 2227 2228 for (int y = 0; y < source.getHeight(); ++y) 2229 for (int x = 0; x < source.getWidth(); ++x) 2230 convertedSource.setPixel(source.getPixelInt(x, y), x, y); // will be clamped to max. representable value 2231 2232 const struct Capture 2233 { 2234 const tcu::ConstPixelBufferAccess& source; 2235 const tcu::ConstPixelBufferAccess& result; 2236 const tcu::Sampler& sampler; 2237 const tcu::IntLookupPrecision& precision; 2238 } capture = 2239 { 2240 convertedSource, result, sampler, precision 2241 }; 2242 2243 const struct Loop : CompareEachPixelInEachRegion 2244 { 2245 Loop (void) {} 2246 2247 bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const 2248 { 2249 const Capture& c = *static_cast<const Capture*>(pUserData); 2250 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY; 2251 const tcu::IVec4 dstColor = c.result.getPixelInt(x, y); 2252 2253 return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor); 2254 } 2255 } loop; 2256 2257 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask); 2258 } 2259 2260 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result, 2261 const tcu::ConstPixelBufferAccess& source) 2262 { 2263 tcu::TestLog& log (m_context.getTestContext().getLog()); 2264 const tcu::TextureFormat dstFormat = result.getFormat(); 2265 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type); 2266 2267 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight()); 2268 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess(); 2269 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f); 2270 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f); 2271 bool ok = false; 2272 2273 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0)); 2274 2275 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || 2276 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 2277 { 2278 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions); 2279 } 2280 else 2281 ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions); 2282 2283 if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)) 2284 tcu::computePixelScaleBias(result, pixelScale, pixelBias); 2285 2286 if (!ok) 2287 { 2288 log << tcu::TestLog::ImageSet("Compare", "Result comparsion") 2289 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) 2290 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) 2291 << tcu::TestLog::EndImageSet; 2292 } 2293 else 2294 { 2295 log << tcu::TestLog::ImageSet("Compare", "Result comparsion") 2296 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) 2297 << tcu::TestLog::EndImageSet; 2298 } 2299 2300 return ok; 2301 } 2302 2303 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result) 2304 { 2305 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR); 2306 const std::string failMessage("Result image is incorrect"); 2307 2308 if (m_params.filter == VK_FILTER_LINEAR) 2309 { 2310 if (tcu::isCombinedDepthStencilType(result.getFormat().type)) 2311 { 2312 if (tcu::hasDepthComponent(result.getFormat().order)) 2313 { 2314 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; 2315 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); 2316 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode); 2317 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode); 2318 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode); 2319 2320 if (!checkLinearFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat)) 2321 return tcu::TestStatus::fail(failMessage); 2322 } 2323 2324 if (tcu::hasStencilComponent(result.getFormat().order)) 2325 { 2326 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; 2327 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); 2328 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode); 2329 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode); 2330 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode); 2331 2332 if (!checkLinearFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat)) 2333 return tcu::TestStatus::fail(failMessage); 2334 } 2335 } 2336 else 2337 { 2338 const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format); 2339 2340 if (!checkLinearFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat)) 2341 return tcu::TestStatus::fail(failMessage); 2342 } 2343 } 2344 else // NEAREST filtering 2345 { 2346 if (tcu::isCombinedDepthStencilType(result.getFormat().type)) 2347 { 2348 if (tcu::hasDepthComponent(result.getFormat().order)) 2349 { 2350 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; 2351 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); 2352 const tcu::ConstPixelBufferAccess depthSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode); 2353 2354 if (!checkNearestFilteredResult(depthResult, depthSource)) 2355 return tcu::TestStatus::fail(failMessage); 2356 } 2357 2358 if (tcu::hasStencilComponent(result.getFormat().order)) 2359 { 2360 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; 2361 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); 2362 const tcu::ConstPixelBufferAccess stencilSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode); 2363 2364 if (!checkNearestFilteredResult(stencilResult, stencilSource)) 2365 return tcu::TestStatus::fail(failMessage); 2366 } 2367 } 2368 else 2369 { 2370 if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess())) 2371 return tcu::TestStatus::fail(failMessage); 2372 } 2373 } 2374 2375 return tcu::TestStatus::pass("Pass"); 2376 } 2377 2378 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color) 2379 { 2380 return isSRGB(format) ? linearToSRGB(color) : color; 2381 } 2382 2383 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter) 2384 { 2385 DE_ASSERT(filter == tcu::Sampler::LINEAR); 2386 DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); 2387 2388 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 2389 filter, filter, 0.0f, false); 2390 2391 float sX = (float)regionExtent.x / (float)dst.getWidth(); 2392 float sY = (float)regionExtent.y / (float)dst.getHeight(); 2393 2394 for (int y = 0; y < dst.getHeight(); y++) 2395 for (int x = 0; x < dst.getWidth(); x++) 2396 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, (float)regionOffset.x + ((float)x+0.5f)*sX, (float)regionOffset.y + ((float)y+0.5f)*sY, 0)), x, y); 2397 } 2398 2399 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode) 2400 { 2401 DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR); 2402 2403 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, 2404 filter, filter, 0.0f, false); 2405 2406 const float sX = (float)src.getWidth() / (float)dst.getWidth(); 2407 const float sY = (float)src.getHeight() / (float)dst.getHeight(); 2408 const float sZ = (float)src.getDepth() / (float)dst.getDepth(); 2409 2410 tcu::Mat2 rotMatrix; 2411 rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f; 2412 rotMatrix(0,1) = 0.0f; 2413 rotMatrix(1,0) = 0.0f; 2414 rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f; 2415 2416 const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0; 2417 const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0; 2418 2419 if (dst.getDepth() == 1 && src.getDepth() == 1) 2420 { 2421 for (int y = 0; y < dst.getHeight(); ++y) 2422 for (int x = 0; x < dst.getWidth(); ++x) 2423 { 2424 const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y); 2425 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, 0)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset); 2426 } 2427 } 2428 else 2429 { 2430 for (int z = 0; z < dst.getDepth(); ++z) 2431 for (int y = 0; y < dst.getHeight(); ++y) 2432 for (int x = 0; x < dst.getWidth(); ++x) 2433 { 2434 const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y); 2435 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset, z); 2436 } 2437 } 2438 } 2439 2440 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode) 2441 { 2442 const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0]; 2443 const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1]; 2444 const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0]; 2445 const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1]; 2446 2447 if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST) 2448 { 2449 //sourceRegion 2450 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x); 2451 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y); 2452 2453 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x); 2454 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y); 2455 2456 //destinationRegion 2457 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x); 2458 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y); 2459 2460 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x); 2461 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y); 2462 } 2463 } 2464 2465 MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2) 2466 { 2467 if (x1.x >= x2.x && x1.y >= x2.y) 2468 { 2469 return MIRROR_MODE_XY; 2470 } 2471 else if (x1.x <= x2.x && x1.y <= x2.y) 2472 { 2473 return MIRROR_MODE_NONE; 2474 } 2475 else if (x1.x <= x2.x && x1.y >= x2.y) 2476 { 2477 return MIRROR_MODE_Y; 2478 } 2479 else if (x1.x >= x2.x && x1.y <= x2.y) 2480 { 2481 return MIRROR_MODE_X; 2482 } 2483 return MIRROR_MODE_LAST; 2484 } 2485 2486 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2) 2487 { 2488 const MirrorMode source = getMirrorMode(s1, s2); 2489 const MirrorMode destination = getMirrorMode(d1, d2); 2490 2491 if (source == destination) 2492 { 2493 return MIRROR_MODE_NONE; 2494 } 2495 else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) || 2496 (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE)) 2497 { 2498 return MIRROR_MODE_Y; 2499 } 2500 else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) || 2501 (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE)) 2502 { 2503 return MIRROR_MODE_X; 2504 } 2505 else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE)) 2506 { 2507 return MIRROR_MODE_XY; 2508 } 2509 return MIRROR_MODE_LAST; 2510 } 2511 2512 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 2513 { 2514 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], 2515 region.imageBlit.srcOffsets[1], 2516 region.imageBlit.dstOffsets[0], 2517 region.imageBlit.dstOffsets[1]); 2518 2519 flipCoordinates(region, mirrorMode); 2520 2521 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0]; 2522 const VkOffset3D srcExtent = 2523 { 2524 region.imageBlit.srcOffsets[1].x - srcOffset.x, 2525 region.imageBlit.srcOffsets[1].y - srcOffset.y, 2526 region.imageBlit.srcOffsets[1].z - srcOffset.z 2527 }; 2528 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0]; 2529 const VkOffset3D dstExtent = 2530 { 2531 region.imageBlit.dstOffsets[1].x - dstOffset.x, 2532 region.imageBlit.dstOffsets[1].y - dstOffset.y, 2533 region.imageBlit.dstOffsets[1].z - dstOffset.z 2534 }; 2535 const tcu::Sampler::FilterMode filter = (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST; 2536 2537 if (tcu::isCombinedDepthStencilType(src.getFormat().type)) 2538 { 2539 DE_ASSERT(src.getFormat() == dst.getFormat()); 2540 // Scale depth. 2541 if (tcu::hasDepthComponent(src.getFormat().order)) 2542 { 2543 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH); 2544 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH); 2545 tcu::scale(dstSubRegion, srcSubRegion, filter); 2546 2547 if (filter == tcu::Sampler::LINEAR) 2548 { 2549 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH); 2550 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH); 2551 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter); 2552 } 2553 } 2554 2555 // Scale stencil. 2556 if (tcu::hasStencilComponent(src.getFormat().order)) 2557 { 2558 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL); 2559 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL); 2560 blit(dstSubRegion, srcSubRegion, filter, mirrorMode); 2561 2562 if (filter == tcu::Sampler::LINEAR) 2563 { 2564 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL); 2565 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL); 2566 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter); 2567 } 2568 } 2569 } 2570 else 2571 { 2572 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y); 2573 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y); 2574 blit(dstSubRegion, srcSubRegion, filter, mirrorMode); 2575 2576 if (filter == tcu::Sampler::LINEAR) 2577 { 2578 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y); 2579 scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter); 2580 } 2581 } 2582 } 2583 2584 void BlittingImages::generateExpectedResult (void) 2585 { 2586 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess(); 2587 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess(); 2588 2589 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth())); 2590 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst); 2591 2592 if (m_params.filter == VK_FILTER_LINEAR) 2593 { 2594 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth())); 2595 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst); 2596 } 2597 2598 for (deUint32 i = 0; i < m_params.regions.size(); i++) 2599 { 2600 CopyRegion region = m_params.regions[i]; 2601 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region); 2602 } 2603 } 2604 2605 class BlitImageTestCase : public vkt::TestCase 2606 { 2607 public: 2608 BlitImageTestCase (tcu::TestContext& testCtx, 2609 const std::string& name, 2610 const std::string& description, 2611 const TestParams params) 2612 : vkt::TestCase (testCtx, name, description) 2613 , m_params (params) 2614 {} 2615 2616 virtual TestInstance* createInstance (Context& context) const 2617 { 2618 return new BlittingImages(context, m_params); 2619 } 2620 private: 2621 TestParams m_params; 2622 }; 2623 2624 class BlittingMipmaps : public CopiesAndBlittingTestInstance 2625 { 2626 public: 2627 BlittingMipmaps (Context& context, 2628 TestParams params); 2629 virtual tcu::TestStatus iterate (void); 2630 protected: 2631 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess()); 2632 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); 2633 virtual void generateExpectedResult (void); 2634 private: 2635 bool checkLinearFilteredResult (void); 2636 bool checkNearestFilteredResult (void); 2637 2638 Move<VkImage> m_source; 2639 de::MovePtr<Allocation> m_sourceImageAlloc; 2640 Move<VkImage> m_destination; 2641 de::MovePtr<Allocation> m_destinationImageAlloc; 2642 2643 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel[16]; 2644 }; 2645 2646 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params) 2647 : CopiesAndBlittingTestInstance (context, params) 2648 { 2649 const InstanceInterface& vki = context.getInstanceInterface(); 2650 const DeviceInterface& vk = context.getDeviceInterface(); 2651 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 2652 const VkDevice vkDevice = context.getDevice(); 2653 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 2654 Allocator& memAlloc = context.getDefaultAllocator(); 2655 2656 { 2657 VkImageFormatProperties properties; 2658 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 2659 m_params.src.image.format, 2660 VK_IMAGE_TYPE_2D, 2661 VK_IMAGE_TILING_OPTIMAL, 2662 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 2663 0, 2664 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) 2665 { 2666 TCU_THROW(NotSupportedError, "Format not supported"); 2667 } 2668 else if ((m_params.src.image.extent.width > properties.maxExtent.width) || 2669 (m_params.src.image.extent.height > properties.maxExtent.height) || 2670 (m_params.src.image.extent.depth > properties.maxExtent.depth)) 2671 { 2672 TCU_THROW(NotSupportedError, "Image size not supported"); 2673 } 2674 } 2675 2676 { 2677 VkImageFormatProperties properties; 2678 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 2679 m_params.dst.image.format, 2680 VK_IMAGE_TYPE_2D, 2681 VK_IMAGE_TILING_OPTIMAL, 2682 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 2683 0, 2684 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) 2685 { 2686 TCU_THROW(NotSupportedError, "Format not supported"); 2687 } 2688 else if ((m_params.dst.image.extent.width > properties.maxExtent.width) || 2689 (m_params.dst.image.extent.height > properties.maxExtent.height) || 2690 (m_params.dst.image.extent.depth > properties.maxExtent.depth)) 2691 { 2692 TCU_THROW(NotSupportedError, "Image size not supported"); 2693 } 2694 else if (m_params.mipLevels > properties.maxMipLevels) 2695 { 2696 TCU_THROW(NotSupportedError, "Number of mip levels not supported"); 2697 } 2698 } 2699 2700 const VkFormatProperties srcFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format); 2701 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT)) 2702 { 2703 TCU_THROW(NotSupportedError, "Format feature blit source not supported"); 2704 } 2705 2706 const VkFormatProperties dstFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format); 2707 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT)) 2708 { 2709 TCU_THROW(NotSupportedError, "Format feature blit destination not supported"); 2710 } 2711 2712 if (m_params.filter == VK_FILTER_LINEAR) 2713 { 2714 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) 2715 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported"); 2716 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) 2717 TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported"); 2718 } 2719 2720 // Create source image 2721 { 2722 const VkImageCreateInfo sourceImageParams = 2723 { 2724 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2725 DE_NULL, // const void* pNext; 2726 0u, // VkImageCreateFlags flags; 2727 m_params.src.image.imageType, // VkImageType imageType; 2728 m_params.src.image.format, // VkFormat format; 2729 getExtent3D(m_params.src.image), // VkExtent3D extent; 2730 1u, // deUint32 mipLevels; 2731 getArraySize(m_params.src.image), // deUint32 arraySize; 2732 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 2733 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2734 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 2735 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 2736 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2737 1u, // deUint32 queueFamilyCount; 2738 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2739 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 2740 }; 2741 2742 m_source = createImage(vk, vkDevice, &sourceImageParams); 2743 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 2744 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); 2745 } 2746 2747 // Create destination image 2748 { 2749 const VkImageCreateInfo destinationImageParams = 2750 { 2751 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2752 DE_NULL, // const void* pNext; 2753 0u, // VkImageCreateFlags flags; 2754 m_params.dst.image.imageType, // VkImageType imageType; 2755 m_params.dst.image.format, // VkFormat format; 2756 getExtent3D(m_params.dst.image), // VkExtent3D extent; 2757 m_params.mipLevels, // deUint32 mipLevels; 2758 getArraySize(m_params.dst.image), // deUint32 arraySize; 2759 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 2760 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2761 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 2762 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 2763 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2764 1u, // deUint32 queueFamilyCount; 2765 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2766 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 2767 }; 2768 2769 m_destination = createImage(vk, vkDevice, &destinationImageParams); 2770 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 2771 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); 2772 } 2773 } 2774 2775 tcu::TestStatus BlittingMipmaps::iterate (void) 2776 { 2777 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); 2778 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); 2779 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, 2780 m_params.src.image.extent.width, 2781 m_params.src.image.extent.height, 2782 m_params.src.image.extent.depth)); 2783 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT); 2784 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, 2785 (int)m_params.dst.image.extent.width, 2786 (int)m_params.dst.image.extent.height, 2787 (int)m_params.dst.image.extent.depth)); 2788 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE); 2789 generateExpectedResult(); 2790 2791 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image); 2792 2793 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels); 2794 2795 const DeviceInterface& vk = m_context.getDeviceInterface(); 2796 const VkDevice vkDevice = m_context.getDevice(); 2797 const VkQueue queue = m_context.getUniversalQueue(); 2798 2799 std::vector<VkImageBlit> regions; 2800 for (deUint32 i = 0; i < m_params.regions.size(); i++) 2801 regions.push_back(m_params.regions[i].imageBlit); 2802 2803 // Copy source image to mip level 0 when generating mipmaps with multiple blit commands 2804 if (!m_params.singleCommand) 2805 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u); 2806 2807 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 2808 { 2809 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 2810 DE_NULL, // const void* pNext; 2811 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 2812 (const VkCommandBufferInheritanceInfo*)DE_NULL, 2813 }; 2814 2815 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 2816 2817 // Blit all mip levels with a single blit command 2818 if (m_params.singleCommand) 2819 { 2820 { 2821 // Source image layout 2822 const VkImageMemoryBarrier srcImageBarrier = 2823 { 2824 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2825 DE_NULL, // const void* pNext; 2826 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2827 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 2828 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 2829 m_params.src.image.operationLayout, // VkImageLayout newLayout; 2830 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2831 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2832 m_source.get(), // VkImage image; 2833 { // VkImageSubresourceRange subresourceRange; 2834 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 2835 0u, // deUint32 baseMipLevel; 2836 1u, // deUint32 mipLevels; 2837 0u, // deUint32 baseArraySlice; 2838 1u // deUint32 arraySize; 2839 } 2840 }; 2841 2842 // Destination image layout 2843 const VkImageMemoryBarrier dstImageBarrier = 2844 { 2845 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2846 DE_NULL, // const void* pNext; 2847 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2848 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 2849 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 2850 m_params.dst.image.operationLayout, // VkImageLayout newLayout; 2851 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2852 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2853 m_destination.get(), // VkImage image; 2854 { // VkImageSubresourceRange subresourceRange; 2855 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 2856 0u, // deUint32 baseMipLevel; 2857 m_params.mipLevels, // deUint32 mipLevels; 2858 0u, // deUint32 baseArraySlice; 2859 1u // deUint32 arraySize; 2860 } 2861 }; 2862 2863 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier); 2864 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier); 2865 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)regions.size(), ®ions[0], m_params.filter); 2866 } 2867 } 2868 // Blit mip levels with multiple blit commands 2869 else 2870 { 2871 // Prepare all mip levels for reading 2872 { 2873 const VkImageMemoryBarrier preImageBarrier = 2874 { 2875 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2876 DE_NULL, // const void* pNext; 2877 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2878 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 2879 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 2880 m_params.src.image.operationLayout, // VkImageLayout newLayout; 2881 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2882 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2883 m_destination.get(), // VkImage image; 2884 { // VkImageSubresourceRange subresourceRange; 2885 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 2886 0u, // deUint32 baseMipLevel; 2887 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels; 2888 0u, // deUint32 baseArraySlice; 2889 1u // deUint32 arraySize; 2890 } 2891 }; 2892 2893 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier); 2894 } 2895 2896 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)regions.size(); regionNdx++) 2897 { 2898 const deUint32 mipLevel = regions[regionNdx].dstSubresource.mipLevel; 2899 2900 // Prepare single mip level for writing 2901 const VkImageMemoryBarrier preImageBarrier = 2902 { 2903 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2904 DE_NULL, // const void* pNext; 2905 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask; 2906 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 2907 m_params.src.image.operationLayout, // VkImageLayout oldLayout; 2908 m_params.dst.image.operationLayout, // VkImageLayout newLayout; 2909 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2910 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2911 m_destination.get(), // VkImage image; 2912 { // VkImageSubresourceRange subresourceRange; 2913 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 2914 mipLevel, // deUint32 baseMipLevel; 2915 1u, // deUint32 mipLevels; 2916 0u, // deUint32 baseArraySlice; 2917 1u // deUint32 arraySize; 2918 } 2919 }; 2920 2921 // Prepare single mip level for reading 2922 const VkImageMemoryBarrier postImageBarrier = 2923 { 2924 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2925 DE_NULL, // const void* pNext; 2926 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 2927 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 2928 m_params.dst.image.operationLayout, // VkImageLayout oldLayout; 2929 m_params.src.image.operationLayout, // VkImageLayout newLayout; 2930 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2931 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2932 m_destination.get(), // VkImage image; 2933 { // VkImageSubresourceRange subresourceRange; 2934 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 2935 mipLevel, // deUint32 baseMipLevel; 2936 1u, // deUint32 mipLevels; 2937 0u, // deUint32 baseArraySlice; 2938 1u // deUint32 arraySize; 2939 } 2940 }; 2941 2942 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier); 2943 vk.cmdBlitImage(*m_cmdBuffer, m_destination.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, 1u, ®ions[regionNdx], m_params.filter); 2944 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 2945 } 2946 2947 // Prepare all mip levels for writing 2948 { 2949 const VkImageMemoryBarrier postImageBarrier = 2950 { 2951 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 2952 DE_NULL, // const void* pNext; 2953 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask; 2954 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 2955 m_params.src.image.operationLayout, // VkImageLayout oldLayout; 2956 m_params.dst.image.operationLayout, // VkImageLayout newLayout; 2957 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 2958 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 2959 m_destination.get(), // VkImage image; 2960 { // VkImageSubresourceRange subresourceRange; 2961 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 2962 0u, // deUint32 baseMipLevel; 2963 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels; 2964 0u, // deUint32 baseArraySlice; 2965 1u // deUint32 arraySize; 2966 } 2967 }; 2968 2969 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 2970 } 2971 } 2972 2973 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 2974 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); 2975 2976 return checkTestResult(); 2977 } 2978 2979 bool BlittingMipmaps::checkLinearFilteredResult (void) 2980 { 2981 tcu::TestLog& log (m_context.getTestContext().getLog()); 2982 bool allLevelsOk = true; 2983 2984 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++) 2985 { 2986 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx); 2987 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess(); 2988 2989 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH : 2990 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL : 2991 tcu::Sampler::MODE_LAST; 2992 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) : 2993 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) : 2994 resultAccess; 2995 const tcu::ConstPixelBufferAccess clampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) : 2996 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) : 2997 m_expectedTextureLevel[mipLevelNdx]->getAccess(); 2998 const tcu::ConstPixelBufferAccess unclampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) : 2999 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) : 3000 m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(); 3001 const tcu::TextureFormat srcFormat = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) : 3002 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) : 3003 mapVkFormat(m_params.src.image.format); 3004 3005 const tcu::TextureFormat dstFormat = result.getFormat(); 3006 bool singleLevelOk = false; 3007 std::vector <CopyRegion> mipLevelRegions; 3008 3009 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++) 3010 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx) 3011 mipLevelRegions.push_back(m_params.regions.at(regionNdx)); 3012 3013 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image."); 3014 3015 if (isFloatFormat(dstFormat)) 3016 { 3017 const bool srcIsSRGB = tcu::isSRGB(srcFormat); 3018 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f); 3019 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat); 3020 const tcu::Vec4 threshold = tcu::max(srcMaxDiff, dstMaxDiff); 3021 3022 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT); 3023 log << tcu::TestLog::EndSection; 3024 3025 if (!singleLevelOk) 3026 { 3027 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image."); 3028 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT); 3029 log << tcu::TestLog::EndSection; 3030 } 3031 } 3032 else 3033 { 3034 tcu::UVec4 threshold; 3035 // Calculate threshold depending on channel width of destination format. 3036 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(dstFormat); 3037 for (deUint32 i = 0; i < 4; ++i) 3038 threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1); 3039 3040 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT); 3041 log << tcu::TestLog::EndSection; 3042 3043 if (!singleLevelOk) 3044 { 3045 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image."); 3046 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT); 3047 log << tcu::TestLog::EndSection; 3048 } 3049 } 3050 allLevelsOk &= singleLevelOk; 3051 } 3052 3053 return allLevelsOk; 3054 } 3055 3056 bool BlittingMipmaps::checkNearestFilteredResult (void) 3057 { 3058 bool allLevelsOk = true; 3059 tcu::TestLog& log (m_context.getTestContext().getLog()); 3060 3061 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++) 3062 { 3063 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx); 3064 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess(); 3065 3066 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH : 3067 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL : 3068 tcu::Sampler::MODE_LAST; 3069 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) : 3070 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) : 3071 resultAccess; 3072 const tcu::ConstPixelBufferAccess source = (m_params.singleCommand || mipLevelNdx == 0) ? // Read from source image 3073 tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) : 3074 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) : 3075 m_sourceTextureLevel->getAccess() 3076 // Read from destination image 3077 : tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) : 3078 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) : 3079 m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(); 3080 const tcu::TextureFormat dstFormat = result.getFormat(); 3081 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type); 3082 bool singleLevelOk = false; 3083 std::vector <CopyRegion> mipLevelRegions; 3084 3085 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++) 3086 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx) 3087 mipLevelRegions.push_back(m_params.regions.at(regionNdx)); 3088 3089 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight()); 3090 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess(); 3091 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f); 3092 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f); 3093 3094 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0)); 3095 3096 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || 3097 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 3098 { 3099 singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions); 3100 } 3101 else 3102 singleLevelOk = floatNearestBlitCompare(source, result, errorMask, mipLevelRegions); 3103 3104 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)) 3105 tcu::computePixelScaleBias(result, pixelScale, pixelBias); 3106 3107 if (!singleLevelOk) 3108 { 3109 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx)) 3110 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) 3111 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias) 3112 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) 3113 << tcu::TestLog::EndImageSet; 3114 } 3115 else 3116 { 3117 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx)) 3118 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) 3119 << tcu::TestLog::EndImageSet; 3120 } 3121 3122 allLevelsOk &= singleLevelOk; 3123 } 3124 3125 return allLevelsOk; 3126 } 3127 3128 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result) 3129 { 3130 DE_UNREF(result); 3131 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR); 3132 const std::string failMessage("Result image is incorrect"); 3133 3134 if (m_params.filter == VK_FILTER_LINEAR) 3135 { 3136 if (!checkLinearFilteredResult()) 3137 return tcu::TestStatus::fail(failMessage); 3138 } 3139 else // NEAREST filtering 3140 { 3141 if (!checkNearestFilteredResult()) 3142 return tcu::TestStatus::fail(failMessage); 3143 } 3144 3145 return tcu::TestStatus::pass("Pass"); 3146 } 3147 3148 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 3149 { 3150 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], 3151 region.imageBlit.srcOffsets[1], 3152 region.imageBlit.dstOffsets[0], 3153 region.imageBlit.dstOffsets[1]); 3154 3155 flipCoordinates(region, mirrorMode); 3156 3157 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0]; 3158 const VkOffset3D srcExtent = 3159 { 3160 region.imageBlit.srcOffsets[1].x - srcOffset.x, 3161 region.imageBlit.srcOffsets[1].y - srcOffset.y, 3162 region.imageBlit.srcOffsets[1].z - srcOffset.z 3163 }; 3164 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0]; 3165 const VkOffset3D dstExtent = 3166 { 3167 region.imageBlit.dstOffsets[1].x - dstOffset.x, 3168 region.imageBlit.dstOffsets[1].y - dstOffset.y, 3169 region.imageBlit.dstOffsets[1].z - dstOffset.z 3170 }; 3171 const tcu::Sampler::FilterMode filter = (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST; 3172 3173 if (tcu::isCombinedDepthStencilType(src.getFormat().type)) 3174 { 3175 DE_ASSERT(src.getFormat() == dst.getFormat()); 3176 // Scale depth. 3177 if (tcu::hasDepthComponent(src.getFormat().order)) 3178 { 3179 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH); 3180 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH); 3181 tcu::scale(dstSubRegion, srcSubRegion, filter); 3182 3183 if (filter == tcu::Sampler::LINEAR) 3184 { 3185 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH); 3186 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH); 3187 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter); 3188 } 3189 } 3190 3191 // Scale stencil. 3192 if (tcu::hasStencilComponent(src.getFormat().order)) 3193 { 3194 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL); 3195 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL); 3196 blit(dstSubRegion, srcSubRegion, filter, mirrorMode); 3197 3198 if (filter == tcu::Sampler::LINEAR) 3199 { 3200 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL); 3201 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL); 3202 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter); 3203 } 3204 } 3205 } 3206 else 3207 { 3208 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y); 3209 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y); 3210 blit(dstSubRegion, srcSubRegion, filter, mirrorMode); 3211 3212 if (filter == tcu::Sampler::LINEAR) 3213 { 3214 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y); 3215 scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter); 3216 } 3217 } 3218 } 3219 3220 void BlittingMipmaps::generateExpectedResult (void) 3221 { 3222 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess(); 3223 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess(); 3224 3225 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++) 3226 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth())); 3227 3228 tcu::copy(m_expectedTextureLevel[0]->getAccess(), src); 3229 3230 if (m_params.filter == VK_FILTER_LINEAR) 3231 { 3232 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++) 3233 m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth())); 3234 3235 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), dst); 3236 } 3237 3238 for (deUint32 i = 0; i < m_params.regions.size(); i++) 3239 { 3240 CopyRegion region = m_params.regions[i]; 3241 copyRegionToTextureLevel(m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(), m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region); 3242 } 3243 } 3244 3245 class BlitMipmapTestCase : public vkt::TestCase 3246 { 3247 public: 3248 BlitMipmapTestCase (tcu::TestContext& testCtx, 3249 const std::string& name, 3250 const std::string& description, 3251 const TestParams params) 3252 : vkt::TestCase (testCtx, name, description) 3253 , m_params (params) 3254 {} 3255 3256 virtual TestInstance* createInstance (Context& context) const 3257 { 3258 return new BlittingMipmaps(context, m_params); 3259 } 3260 private: 3261 TestParams m_params; 3262 }; 3263 3264 // Resolve image to image. 3265 3266 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE}; 3267 class ResolveImageToImage : public CopiesAndBlittingTestInstance 3268 { 3269 public: 3270 ResolveImageToImage (Context& context, 3271 TestParams params, 3272 const ResolveImageToImageOptions options); 3273 virtual tcu::TestStatus iterate (void); 3274 protected: 3275 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess()); 3276 void copyMSImageToMSImage (void); 3277 private: 3278 Move<VkImage> m_multisampledImage; 3279 de::MovePtr<Allocation> m_multisampledImageAlloc; 3280 3281 Move<VkImage> m_destination; 3282 de::MovePtr<Allocation> m_destinationImageAlloc; 3283 3284 Move<VkImage> m_multisampledCopyImage; 3285 de::MovePtr<Allocation> m_multisampledCopyImageAlloc; 3286 3287 const ResolveImageToImageOptions m_options; 3288 3289 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, 3290 tcu::PixelBufferAccess dst, 3291 CopyRegion region); 3292 }; 3293 3294 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options) 3295 : CopiesAndBlittingTestInstance (context, params) 3296 , m_options (options) 3297 { 3298 const VkSampleCountFlagBits rasterizationSamples = m_params.samples; 3299 3300 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples)) 3301 throw tcu::NotSupportedError("Unsupported number of rasterization samples"); 3302 3303 const InstanceInterface& vki = context.getInstanceInterface(); 3304 const DeviceInterface& vk = context.getDeviceInterface(); 3305 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); 3306 const VkDevice vkDevice = context.getDevice(); 3307 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 3308 Allocator& memAlloc = m_context.getDefaultAllocator(); 3309 3310 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 3311 Move<VkRenderPass> renderPass; 3312 3313 Move<VkShaderModule> vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); 3314 Move<VkShaderModule> fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); 3315 std::vector<tcu::Vec4> vertices; 3316 3317 Move<VkBuffer> vertexBuffer; 3318 de::MovePtr<Allocation> vertexBufferAlloc; 3319 3320 Move<VkPipelineLayout> pipelineLayout; 3321 Move<VkPipeline> graphicsPipeline; 3322 3323 VkImageFormatProperties properties; 3324 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 3325 m_params.src.image.format, 3326 m_params.src.image.imageType, 3327 VK_IMAGE_TILING_OPTIMAL, 3328 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, 3329 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) || 3330 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), 3331 m_params.dst.image.format, 3332 m_params.dst.image.imageType, 3333 VK_IMAGE_TILING_OPTIMAL, 3334 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0, 3335 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) 3336 { 3337 TCU_THROW(NotSupportedError, "Format not supported"); 3338 } 3339 3340 // Create color image. 3341 { 3342 VkImageCreateInfo colorImageParams = 3343 { 3344 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3345 DE_NULL, // const void* pNext; 3346 0u, // VkImageCreateFlags flags; 3347 m_params.src.image.imageType, // VkImageType imageType; 3348 m_params.src.image.format, // VkFormat format; 3349 getExtent3D(m_params.src.image), // VkExtent3D extent; 3350 1u, // deUint32 mipLevels; 3351 getArraySize(m_params.src.image), // deUint32 arrayLayers; 3352 rasterizationSamples, // VkSampleCountFlagBits samples; 3353 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3354 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 3355 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3356 1u, // deUint32 queueFamilyIndexCount; 3357 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3358 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 3359 }; 3360 3361 m_multisampledImage = createImage(vk, vkDevice, &colorImageParams); 3362 3363 // Allocate and bind color image memory. 3364 m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 3365 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset())); 3366 3367 switch (m_options) 3368 { 3369 case COPY_MS_IMAGE_TO_MS_IMAGE: 3370 { 3371 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3372 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams); 3373 // Allocate and bind color image memory. 3374 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 3375 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset())); 3376 break; 3377 } 3378 3379 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE: 3380 { 3381 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 3382 colorImageParams.arrayLayers = getArraySize(m_params.dst.image); 3383 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams); 3384 // Allocate and bind color image memory. 3385 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 3386 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset())); 3387 break; 3388 } 3389 3390 default : 3391 break; 3392 } 3393 } 3394 3395 // Create destination image. 3396 { 3397 const VkImageCreateInfo destinationImageParams = 3398 { 3399 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3400 DE_NULL, // const void* pNext; 3401 0u, // VkImageCreateFlags flags; 3402 m_params.dst.image.imageType, // VkImageType imageType; 3403 m_params.dst.image.format, // VkFormat format; 3404 getExtent3D(m_params.dst.image), // VkExtent3D extent; 3405 1u, // deUint32 mipLevels; 3406 getArraySize(m_params.dst.image), // deUint32 arraySize; 3407 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 3408 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3409 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 3410 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage; 3411 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3412 1u, // deUint32 queueFamilyCount; 3413 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3414 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 3415 }; 3416 3417 m_destination = createImage(vk, vkDevice, &destinationImageParams); 3418 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); 3419 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); 3420 } 3421 3422 // Barriers for copying image to buffer 3423 VkImageMemoryBarrier srcImageBarrier = 3424 { 3425 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3426 DE_NULL, // const void* pNext; 3427 0u, // VkAccessFlags srcAccessMask; 3428 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 3429 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 3430 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 3431 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3432 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3433 m_multisampledImage.get(), // VkImage image; 3434 { // VkImageSubresourceRange subresourceRange; 3435 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 3436 0u, // deUint32 baseMipLevel; 3437 1u, // deUint32 mipLevels; 3438 0u, // deUint32 baseArraySlice; 3439 getArraySize(m_params.src.image) // deUint32 arraySize; 3440 } 3441 }; 3442 3443 // Create render pass. 3444 { 3445 const VkAttachmentDescription attachmentDescriptions[1] = 3446 { 3447 { 3448 0u, // VkAttachmentDescriptionFlags flags; 3449 m_params.src.image.format, // VkFormat format; 3450 rasterizationSamples, // VkSampleCountFlagBits samples; 3451 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 3452 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 3453 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 3454 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 3455 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3456 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 3457 }, 3458 }; 3459 3460 const VkAttachmentReference colorAttachmentReference = 3461 { 3462 0u, // deUint32 attachment; 3463 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 3464 }; 3465 3466 const VkSubpassDescription subpassDescription = 3467 { 3468 0u, // VkSubpassDescriptionFlags flags; 3469 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 3470 0u, // deUint32 inputAttachmentCount; 3471 DE_NULL, // const VkAttachmentReference* pInputAttachments; 3472 1u, // deUint32 colorAttachmentCount; 3473 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 3474 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 3475 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 3476 0u, // deUint32 preserveAttachmentCount; 3477 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 3478 }; 3479 3480 const VkRenderPassCreateInfo renderPassParams = 3481 { 3482 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 3483 DE_NULL, // const void* pNext; 3484 0u, // VkRenderPassCreateFlags flags; 3485 1u, // deUint32 attachmentCount; 3486 attachmentDescriptions, // const VkAttachmentDescription* pAttachments; 3487 1u, // deUint32 subpassCount; 3488 &subpassDescription, // const VkSubpassDescription* pSubpasses; 3489 0u, // deUint32 dependencyCount; 3490 DE_NULL // const VkSubpassDependency* pDependencies; 3491 }; 3492 3493 renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 3494 } 3495 3496 // Create pipeline layout 3497 { 3498 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 3499 { 3500 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 3501 DE_NULL, // const void* pNext; 3502 0u, // VkPipelineLayoutCreateFlags flags; 3503 0u, // deUint32 setLayoutCount; 3504 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 3505 0u, // deUint32 pushConstantRangeCount; 3506 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 3507 }; 3508 3509 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 3510 } 3511 3512 // Create upper half triangle. 3513 { 3514 const tcu::Vec4 a (-1.0, -1.0, 0.0, 1.0); 3515 const tcu::Vec4 b (1.0, -1.0, 0.0, 1.0); 3516 const tcu::Vec4 c (1.0, 1.0, 0.0, 1.0); 3517 // Add triangle. 3518 vertices.push_back(a); 3519 vertices.push_back(c); 3520 vertices.push_back(b); 3521 } 3522 3523 // Create vertex buffer. 3524 { 3525 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4); 3526 const VkBufferCreateInfo vertexBufferParams = 3527 { 3528 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3529 DE_NULL, // const void* pNext; 3530 0u, // VkBufferCreateFlags flags; 3531 vertexDataSize, // VkDeviceSize size; 3532 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 3533 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3534 1u, // deUint32 queueFamilyIndexCount; 3535 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 3536 }; 3537 3538 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 3539 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); 3540 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset())); 3541 3542 // Load vertices into vertex buffer. 3543 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize); 3544 flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize); 3545 } 3546 3547 { 3548 Move<VkFramebuffer> framebuffer; 3549 Move<VkImageView> sourceAttachmentView; 3550 3551 // Create color attachment view. 3552 { 3553 const VkImageViewCreateInfo colorAttachmentViewParams = 3554 { 3555 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3556 DE_NULL, // const void* pNext; 3557 0u, // VkImageViewCreateFlags flags; 3558 *m_multisampledImage, // VkImage image; 3559 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3560 m_params.src.image.format, // VkFormat format; 3561 componentMappingRGBA, // VkComponentMapping components; 3562 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 3563 }; 3564 sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 3565 } 3566 3567 // Create framebuffer 3568 { 3569 const VkImageView attachments[1] = 3570 { 3571 *sourceAttachmentView, 3572 }; 3573 3574 const VkFramebufferCreateInfo framebufferParams = 3575 { 3576 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 3577 DE_NULL, // const void* pNext; 3578 0u, // VkFramebufferCreateFlags flags; 3579 *renderPass, // VkRenderPass renderPass; 3580 1u, // deUint32 attachmentCount; 3581 attachments, // const VkImageView* pAttachments; 3582 m_params.src.image.extent.width, // deUint32 width; 3583 m_params.src.image.extent.height, // deUint32 height; 3584 1u // deUint32 layers; 3585 }; 3586 3587 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 3588 } 3589 3590 // Create pipeline 3591 { 3592 const VkPipelineShaderStageCreateInfo shaderStageParams[2] = 3593 { 3594 { 3595 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 3596 DE_NULL, // const void* pNext; 3597 0u, // VkPipelineShaderStageCreateFlags flags; 3598 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 3599 *vertexShaderModule, // VkShaderModule module; 3600 "main", // const char* pName; 3601 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 3602 }, 3603 { 3604 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 3605 DE_NULL, // const void* pNext; 3606 0u, // VkPipelineShaderStageCreateFlags flags; 3607 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 3608 *fragmentShaderModule, // VkShaderModule module; 3609 "main", // const char* pName; 3610 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 3611 } 3612 }; 3613 3614 const VkVertexInputBindingDescription vertexInputBindingDescription = 3615 { 3616 0u, // deUint32 binding; 3617 sizeof(tcu::Vec4), // deUint32 stride; 3618 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; 3619 }; 3620 3621 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[1] = 3622 { 3623 { 3624 0u, // deUint32 location; 3625 0u, // deUint32 binding; 3626 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 3627 0u // deUint32 offset; 3628 } 3629 }; 3630 3631 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 3632 { 3633 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 3634 DE_NULL, // const void* pNext; 3635 0u, // VkPipelineVertexInputStateCreateFlags flags; 3636 1u, // deUint32 vertexBindingDescriptionCount; 3637 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 3638 1u, // deUint32 vertexAttributeDescriptionCount; 3639 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 3640 }; 3641 3642 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 3643 { 3644 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 3645 DE_NULL, // const void* pNext; 3646 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 3647 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 3648 false // VkBool32 primitiveRestartEnable; 3649 }; 3650 3651 const VkViewport viewport = 3652 { 3653 0.0f, // float x; 3654 0.0f, // float y; 3655 (float)m_params.src.image.extent.width, // float width; 3656 (float)m_params.src.image.extent.height,// float height; 3657 0.0f, // float minDepth; 3658 1.0f // float maxDepth; 3659 }; 3660 3661 const VkRect2D scissor = 3662 { 3663 { 0, 0 }, // VkOffset2D offset; 3664 { m_params.src.image.extent.width, m_params.src.image.extent.height } // VkExtent2D extent; 3665 }; 3666 3667 const VkPipelineViewportStateCreateInfo viewportStateParams = 3668 { 3669 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 3670 DE_NULL, // const void* pNext; 3671 0u, // VkPipelineViewportStateCreateFlags flags; 3672 1u, // deUint32 viewportCount; 3673 &viewport, // const VkViewport* pViewports; 3674 1u, // deUint32 scissorCount; 3675 &scissor // const VkRect2D* pScissors; 3676 }; 3677 3678 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 3679 { 3680 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 3681 DE_NULL, // const void* pNext; 3682 0u, // VkPipelineRasterizationStateCreateFlags flags; 3683 false, // VkBool32 depthClampEnable; 3684 false, // VkBool32 rasterizerDiscardEnable; 3685 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 3686 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 3687 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 3688 VK_FALSE, // VkBool32 depthBiasEnable; 3689 0.0f, // float depthBiasConstantFactor; 3690 0.0f, // float depthBiasClamp; 3691 0.0f, // float depthBiasSlopeFactor; 3692 1.0f // float lineWidth; 3693 }; 3694 3695 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 3696 { 3697 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 3698 DE_NULL, // const void* pNext; 3699 0u, // VkPipelineMultisampleStateCreateFlags flags; 3700 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; 3701 VK_FALSE, // VkBool32 sampleShadingEnable; 3702 0.0f, // float minSampleShading; 3703 DE_NULL, // const VkSampleMask* pSampleMask; 3704 VK_FALSE, // VkBool32 alphaToCoverageEnable; 3705 VK_FALSE // VkBool32 alphaToOneEnable; 3706 }; 3707 3708 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 3709 { 3710 false, // VkBool32 blendEnable; 3711 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 3712 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 3713 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 3714 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 3715 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 3716 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 3717 (VK_COLOR_COMPONENT_R_BIT | 3718 VK_COLOR_COMPONENT_G_BIT | 3719 VK_COLOR_COMPONENT_B_BIT | 3720 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask; 3721 }; 3722 3723 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 3724 { 3725 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 3726 DE_NULL, // const void* pNext; 3727 0u, // VkPipelineColorBlendStateCreateFlags flags; 3728 false, // VkBool32 logicOpEnable; 3729 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 3730 1u, // deUint32 attachmentCount; 3731 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 3732 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 3733 }; 3734 3735 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 3736 { 3737 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 3738 DE_NULL, // const void* pNext; 3739 0u, // VkPipelineCreateFlags flags; 3740 2u, // deUint32 stageCount; 3741 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; 3742 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 3743 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 3744 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 3745 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 3746 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 3747 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 3748 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 3749 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 3750 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 3751 *pipelineLayout, // VkPipelineLayout layout; 3752 *renderPass, // VkRenderPass renderPass; 3753 0u, // deUint32 subpass; 3754 0u, // VkPipeline basePipelineHandle; 3755 0u // deInt32 basePipelineIndex; 3756 }; 3757 3758 graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 3759 } 3760 3761 // Create command buffer 3762 { 3763 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 3764 { 3765 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 3766 DE_NULL, // const void* pNext; 3767 0u, // VkCommandBufferUsageFlags flags; 3768 (const VkCommandBufferInheritanceInfo*)DE_NULL, 3769 }; 3770 3771 const VkClearValue clearValues[1] = 3772 { 3773 makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f), 3774 }; 3775 3776 const VkRenderPassBeginInfo renderPassBeginInfo = 3777 { 3778 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 3779 DE_NULL, // const void* pNext; 3780 *renderPass, // VkRenderPass renderPass; 3781 *framebuffer, // VkFramebuffer framebuffer; 3782 { 3783 { 0, 0 }, 3784 { m_params.src.image.extent.width, m_params.src.image.extent.height } 3785 }, // VkRect2D renderArea; 3786 1u, // deUint32 clearValueCount; 3787 clearValues // const VkClearValue* pClearValues; 3788 }; 3789 3790 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 3791 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier); 3792 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 3793 3794 const VkDeviceSize vertexBufferOffset = 0u; 3795 3796 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); 3797 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); 3798 vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0); 3799 3800 vk.cmdEndRenderPass(*m_cmdBuffer); 3801 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 3802 } 3803 3804 // Queue submit. 3805 { 3806 const VkQueue queue = m_context.getUniversalQueue(); 3807 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); 3808 } 3809 } 3810 } 3811 3812 tcu::TestStatus ResolveImageToImage::iterate (void) 3813 { 3814 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); 3815 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); 3816 3817 // upload the destination image 3818 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, 3819 (int)m_params.dst.image.extent.width, 3820 (int)m_params.dst.image.extent.height, 3821 (int)m_params.dst.image.extent.depth)); 3822 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth); 3823 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image); 3824 3825 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, 3826 (int)m_params.src.image.extent.width, 3827 (int)m_params.src.image.extent.height, 3828 (int)m_params.dst.image.extent.depth)); 3829 3830 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE); 3831 generateExpectedResult(); 3832 3833 switch (m_options) 3834 { 3835 case COPY_MS_IMAGE_TO_MS_IMAGE: 3836 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE: 3837 copyMSImageToMSImage(); 3838 break; 3839 default: 3840 break; 3841 } 3842 3843 const DeviceInterface& vk = m_context.getDeviceInterface(); 3844 const VkDevice vkDevice = m_context.getDevice(); 3845 const VkQueue queue = m_context.getUniversalQueue(); 3846 3847 std::vector<VkImageResolve> imageResolves; 3848 for (deUint32 i = 0; i < m_params.regions.size(); i++) 3849 imageResolves.push_back(m_params.regions[i].imageResolve); 3850 3851 const VkImageMemoryBarrier imageBarriers[] = 3852 { 3853 // source image 3854 { 3855 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3856 DE_NULL, // const void* pNext; 3857 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 3858 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 3859 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 3860 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 3861 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3862 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3863 m_multisampledImage.get(), // VkImage image; 3864 { // VkImageSubresourceRange subresourceRange; 3865 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 3866 0u, // deUint32 baseMipLevel; 3867 1u, // deUint32 mipLevels; 3868 0u, // deUint32 baseArraySlice; 3869 getArraySize(m_params.src.image) // deUint32 arraySize; 3870 } 3871 }, 3872 // destination image 3873 { 3874 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3875 DE_NULL, // const void* pNext; 3876 0u, // VkAccessFlags srcAccessMask; 3877 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 3878 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 3879 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 3880 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3881 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3882 m_destination.get(), // VkImage image; 3883 { // VkImageSubresourceRange subresourceRange; 3884 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 3885 0u, // deUint32 baseMipLevel; 3886 1u, // deUint32 mipLevels; 3887 0u, // deUint32 baseArraySlice; 3888 getArraySize(m_params.dst.image) // deUint32 arraySize; 3889 } 3890 }, 3891 }; 3892 3893 const VkImageMemoryBarrier postImageBarrier = 3894 { 3895 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 3896 DE_NULL, // const void* pNext; 3897 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 3898 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 3899 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 3900 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 3901 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 3902 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 3903 m_destination.get(), // VkImage image; 3904 { // VkImageSubresourceRange subresourceRange; 3905 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; 3906 0u, // deUint32 baseMipLevel; 3907 1u, // deUint32 mipLevels; 3908 0u, // deUint32 baseArraySlice; 3909 getArraySize(m_params.dst.image) // deUint32 arraySize; 3910 } 3911 }; 3912 3913 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 3914 { 3915 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 3916 DE_NULL, // const void* pNext; 3917 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 3918 (const VkCommandBufferInheritanceInfo*)DE_NULL, 3919 }; 3920 3921 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 3922 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers); 3923 vk.cmdResolveImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data()); 3924 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 3925 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 3926 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); 3927 3928 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image); 3929 3930 return checkTestResult(resultTextureLevel->getAccess()); 3931 } 3932 3933 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result) 3934 { 3935 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess(); 3936 const float fuzzyThreshold = 0.01f; 3937 3938 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx) 3939 { 3940 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u); 3941 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u); 3942 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT)) 3943 return tcu::TestStatus::fail("CopiesAndBlitting test"); 3944 } 3945 3946 return tcu::TestStatus::pass("CopiesAndBlitting test"); 3947 } 3948 3949 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) 3950 { 3951 VkOffset3D srcOffset = region.imageResolve.srcOffset; 3952 srcOffset.z = region.imageResolve.srcSubresource.baseArrayLayer; 3953 VkOffset3D dstOffset = region.imageResolve.dstOffset; 3954 dstOffset.z = region.imageResolve.dstSubresource.baseArrayLayer; 3955 VkExtent3D extent = region.imageResolve.extent; 3956 3957 const tcu::ConstPixelBufferAccess srcSubRegion = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth); 3958 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy. 3959 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr()); 3960 const tcu::PixelBufferAccess dstSubRegion = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth); 3961 3962 tcu::copy(dstSubRegion, srcSubRegion); 3963 } 3964 3965 void ResolveImageToImage::copyMSImageToMSImage (void) 3966 { 3967 const DeviceInterface& vk = m_context.getDeviceInterface(); 3968 const VkDevice vkDevice = m_context.getDevice(); 3969 const VkQueue queue = m_context.getUniversalQueue(); 3970 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); 3971 std::vector<VkImageCopy> imageCopies; 3972 3973 for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx) 3974 { 3975 const VkImageSubresourceLayers sourceSubresourceLayers = 3976 { 3977 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 3978 0u, // uint32_t mipLevel; 3979 0u, // uint32_t baseArrayLayer; 3980 1u // uint32_t layerCount; 3981 }; 3982 3983 const VkImageSubresourceLayers destinationSubresourceLayers = 3984 { 3985 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat) 3986 0u, // uint32_t mipLevel; 3987 layerNdx, // uint32_t baseArrayLayer; 3988 1u // uint32_t layerCount; 3989 }; 3990 3991 const VkImageCopy imageCopy = 3992 { 3993 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource; 3994 {0, 0, 0}, // VkOffset3D srcOffset; 3995 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource; 3996 {0, 0, 0}, // VkOffset3D dstOffset; 3997 getExtent3D(m_params.src.image), // VkExtent3D extent; 3998 }; 3999 imageCopies.push_back(imageCopy); 4000 } 4001 4002 const VkImageMemoryBarrier imageBarriers[] = 4003 { 4004 // source image 4005 { 4006 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4007 DE_NULL, // const void* pNext; 4008 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 4009 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 4010 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 4011 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 4012 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4013 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4014 m_multisampledImage.get(), // VkImage image; 4015 { // VkImageSubresourceRange subresourceRange; 4016 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 4017 0u, // deUint32 baseMipLevel; 4018 1u, // deUint32 mipLevels; 4019 0u, // deUint32 baseArraySlice; 4020 getArraySize(m_params.src.image) // deUint32 arraySize; 4021 } 4022 }, 4023 // destination image 4024 { 4025 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4026 DE_NULL, // const void* pNext; 4027 0, // VkAccessFlags srcAccessMask; 4028 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 4029 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 4030 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 4031 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4032 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4033 m_multisampledCopyImage.get(), // VkImage image; 4034 { // VkImageSubresourceRange subresourceRange; 4035 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 4036 0u, // deUint32 baseMipLevel; 4037 1u, // deUint32 mipLevels; 4038 0u, // deUint32 baseArraySlice; 4039 getArraySize(m_params.dst.image) // deUint32 arraySize; 4040 } 4041 }, 4042 }; 4043 4044 const VkImageMemoryBarrier postImageBarriers = 4045 // source image 4046 { 4047 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4048 DE_NULL, // const void* pNext; 4049 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 4050 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 4051 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 4052 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 4053 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 4054 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 4055 m_multisampledCopyImage.get(), // VkImage image; 4056 { // VkImageSubresourceRange subresourceRange; 4057 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; 4058 0u, // deUint32 baseMipLevel; 4059 1u, // deUint32 mipLevels; 4060 0u, // deUint32 baseArraySlice; 4061 getArraySize(m_params.dst.image) // deUint32 arraySize; 4062 } 4063 }; 4064 4065 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 4066 { 4067 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 4068 DE_NULL, // const void* pNext; 4069 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 4070 (const VkCommandBufferInheritanceInfo*)DE_NULL, 4071 }; 4072 4073 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 4074 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers); 4075 vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)imageCopies.size(), imageCopies.data()); 4076 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers); 4077 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 4078 4079 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); 4080 4081 m_multisampledImage = m_multisampledCopyImage; 4082 } 4083 4084 class ResolveImageToImageTestCase : public vkt::TestCase 4085 { 4086 public: 4087 ResolveImageToImageTestCase (tcu::TestContext& testCtx, 4088 const std::string& name, 4089 const std::string& description, 4090 const TestParams params, 4091 const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION) 4092 : vkt::TestCase (testCtx, name, description) 4093 , m_params (params) 4094 , m_options (options) 4095 {} 4096 virtual void initPrograms (SourceCollections& programCollection) const; 4097 4098 virtual TestInstance* createInstance (Context& context) const 4099 { 4100 return new ResolveImageToImage(context, m_params, m_options); 4101 } 4102 private: 4103 TestParams m_params; 4104 const ResolveImageToImageOptions m_options; 4105 }; 4106 4107 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const 4108 { 4109 programCollection.glslSources.add("vert") << glu::VertexSource( 4110 "#version 310 es\n" 4111 "layout (location = 0) in highp vec4 a_position;\n" 4112 "void main()\n" 4113 "{\n" 4114 " gl_Position = a_position;\n" 4115 "}\n"); 4116 4117 4118 programCollection.glslSources.add("frag") << glu::FragmentSource( 4119 "#version 310 es\n" 4120 "layout (location = 0) out highp vec4 o_color;\n" 4121 "void main()\n" 4122 "{\n" 4123 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 4124 "}\n"); 4125 } 4126 4127 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag) 4128 { 4129 return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16)); 4130 } 4131 4132 std::string getFormatCaseName (VkFormat format) 4133 { 4134 return de::toLower(de::toString(getFormatStr(format)).substr(10)); 4135 } 4136 4137 std::string getImageLayoutCaseName (VkImageLayout layout) 4138 { 4139 switch (layout) 4140 { 4141 case VK_IMAGE_LAYOUT_GENERAL: 4142 return "general"; 4143 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 4144 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 4145 return "optimal"; 4146 default: 4147 DE_ASSERT(false); 4148 return ""; 4149 } 4150 } 4151 4152 const deInt32 defaultSize = 64; 4153 const deInt32 defaultHalfSize = defaultSize / 2; 4154 const deInt32 defaultFourthSize = defaultSize / 4; 4155 const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1}; 4156 const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1}; 4157 4158 const VkImageSubresourceLayers defaultSourceLayer = 4159 { 4160 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4161 0u, // uint32_t mipLevel; 4162 0u, // uint32_t baseArrayLayer; 4163 1u, // uint32_t layerCount; 4164 }; 4165 4166 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4167 { 4168 tcu::TestContext& testCtx = group->getTestContext(); 4169 4170 { 4171 TestParams params; 4172 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4173 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4174 params.src.image.extent = defaultExtent; 4175 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4176 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4177 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 4178 params.dst.image.extent = defaultExtent; 4179 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4180 params.allocationKind = allocationKind; 4181 4182 { 4183 const VkImageCopy testCopy = 4184 { 4185 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 4186 {0, 0, 0}, // VkOffset3D srcOffset; 4187 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 4188 {0, 0, 0}, // VkOffset3D dstOffset; 4189 defaultExtent, // VkExtent3D extent; 4190 }; 4191 4192 CopyRegion imageCopy; 4193 imageCopy.imageCopy = testCopy; 4194 4195 params.regions.push_back(imageCopy); 4196 } 4197 4198 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params)); 4199 } 4200 4201 { 4202 TestParams params; 4203 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4204 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4205 params.src.image.extent = defaultExtent; 4206 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4207 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4208 params.dst.image.format = VK_FORMAT_R32_UINT; 4209 params.dst.image.extent = defaultExtent; 4210 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4211 params.allocationKind = allocationKind; 4212 4213 { 4214 const VkImageCopy testCopy = 4215 { 4216 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 4217 {0, 0, 0}, // VkOffset3D srcOffset; 4218 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 4219 {0, 0, 0}, // VkOffset3D dstOffset; 4220 defaultExtent, // VkExtent3D extent; 4221 }; 4222 4223 CopyRegion imageCopy; 4224 imageCopy.imageCopy = testCopy; 4225 4226 params.regions.push_back(imageCopy); 4227 } 4228 4229 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params)); 4230 } 4231 4232 { 4233 TestParams params; 4234 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4235 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4236 params.src.image.extent = defaultExtent; 4237 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4238 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4239 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 4240 params.dst.image.extent = defaultExtent; 4241 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4242 params.allocationKind = allocationKind; 4243 4244 { 4245 const VkImageCopy testCopy = 4246 { 4247 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 4248 {0, 0, 0}, // VkOffset3D srcOffset; 4249 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 4250 {defaultFourthSize, defaultFourthSize / 2, 0}, // VkOffset3D dstOffset; 4251 {defaultFourthSize / 2, defaultFourthSize / 2, 1}, // VkExtent3D extent; 4252 }; 4253 4254 CopyRegion imageCopy; 4255 imageCopy.imageCopy = testCopy; 4256 4257 params.regions.push_back(imageCopy); 4258 } 4259 4260 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params)); 4261 } 4262 4263 { 4264 TestParams params; 4265 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4266 params.src.image.format = VK_FORMAT_D32_SFLOAT; 4267 params.src.image.extent = defaultExtent; 4268 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4269 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4270 params.dst.image.format = VK_FORMAT_D32_SFLOAT; 4271 params.dst.image.extent = defaultExtent; 4272 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4273 params.allocationKind = allocationKind; 4274 4275 { 4276 const VkImageSubresourceLayers sourceLayer = 4277 { 4278 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask; 4279 0u, // uint32_t mipLevel; 4280 0u, // uint32_t baseArrayLayer; 4281 1u // uint32_t layerCount; 4282 }; 4283 const VkImageCopy testCopy = 4284 { 4285 sourceLayer, // VkImageSubresourceLayers srcSubresource; 4286 {0, 0, 0}, // VkOffset3D srcOffset; 4287 sourceLayer, // VkImageSubresourceLayers dstSubresource; 4288 {defaultFourthSize, defaultFourthSize / 2, 0}, // VkOffset3D dstOffset; 4289 {defaultFourthSize / 2, defaultFourthSize / 2, 1}, // VkExtent3D extent; 4290 }; 4291 4292 CopyRegion imageCopy; 4293 imageCopy.imageCopy = testCopy; 4294 4295 params.regions.push_back(imageCopy); 4296 } 4297 4298 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params)); 4299 } 4300 4301 { 4302 TestParams params; 4303 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4304 params.src.image.format = VK_FORMAT_S8_UINT; 4305 params.src.image.extent = defaultExtent; 4306 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4307 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4308 params.dst.image.format = VK_FORMAT_S8_UINT; 4309 params.dst.image.extent = defaultExtent; 4310 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4311 params.allocationKind = allocationKind; 4312 4313 { 4314 const VkImageSubresourceLayers sourceLayer = 4315 { 4316 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask; 4317 0u, // uint32_t mipLevel; 4318 0u, // uint32_t baseArrayLayer; 4319 1u // uint32_t layerCount; 4320 }; 4321 const VkImageCopy testCopy = 4322 { 4323 sourceLayer, // VkImageSubresourceLayers srcSubresource; 4324 {0, 0, 0}, // VkOffset3D srcOffset; 4325 sourceLayer, // VkImageSubresourceLayers dstSubresource; 4326 {defaultFourthSize, defaultFourthSize / 2, 0}, // VkOffset3D dstOffset; 4327 {defaultFourthSize / 2, defaultFourthSize / 2, 1}, // VkExtent3D extent; 4328 }; 4329 4330 CopyRegion imageCopy; 4331 imageCopy.imageCopy = testCopy; 4332 4333 params.regions.push_back(imageCopy); 4334 } 4335 4336 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params)); 4337 } 4338 } 4339 4340 struct CopyColorTestParams 4341 { 4342 TestParams params; 4343 const VkFormat* compatibleFormats; 4344 }; 4345 4346 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params) 4347 { 4348 const VkImageLayout copySrcLayouts[] = 4349 { 4350 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4351 VK_IMAGE_LAYOUT_GENERAL 4352 }; 4353 const VkImageLayout copyDstLayouts[] = 4354 { 4355 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 4356 VK_IMAGE_LAYOUT_GENERAL 4357 }; 4358 4359 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx) 4360 { 4361 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx]; 4362 4363 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx) 4364 { 4365 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx]; 4366 4367 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" + 4368 getImageLayoutCaseName(params.dst.image.operationLayout); 4369 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) + 4370 " to " + getImageLayoutCaseName(params.dst.image.operationLayout); 4371 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params)); 4372 } 4373 } 4374 } 4375 4376 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams) 4377 { 4378 bool result = true; 4379 4380 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED) 4381 { 4382 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty()); 4383 4384 result = 4385 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) || 4386 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format); 4387 } 4388 4389 return result; 4390 } 4391 4392 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams) 4393 { 4394 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex) 4395 { 4396 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex]; 4397 if (!isSupportedByFramework(testParams.params.dst.image.format)) 4398 continue; 4399 4400 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams)) 4401 continue; 4402 4403 const std::string description = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format); 4404 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params); 4405 } 4406 } 4407 4408 const VkFormat compatibleFormats8Bit[] = 4409 { 4410 VK_FORMAT_R4G4_UNORM_PACK8, 4411 VK_FORMAT_R8_UNORM, 4412 VK_FORMAT_R8_SNORM, 4413 VK_FORMAT_R8_USCALED, 4414 VK_FORMAT_R8_SSCALED, 4415 VK_FORMAT_R8_UINT, 4416 VK_FORMAT_R8_SINT, 4417 VK_FORMAT_R8_SRGB, 4418 4419 VK_FORMAT_UNDEFINED 4420 }; 4421 const VkFormat compatibleFormats16Bit[] = 4422 { 4423 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 4424 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 4425 VK_FORMAT_R5G6B5_UNORM_PACK16, 4426 VK_FORMAT_B5G6R5_UNORM_PACK16, 4427 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 4428 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 4429 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 4430 VK_FORMAT_R8G8_UNORM, 4431 VK_FORMAT_R8G8_SNORM, 4432 VK_FORMAT_R8G8_USCALED, 4433 VK_FORMAT_R8G8_SSCALED, 4434 VK_FORMAT_R8G8_UINT, 4435 VK_FORMAT_R8G8_SINT, 4436 VK_FORMAT_R8G8_SRGB, 4437 VK_FORMAT_R16_UNORM, 4438 VK_FORMAT_R16_SNORM, 4439 VK_FORMAT_R16_USCALED, 4440 VK_FORMAT_R16_SSCALED, 4441 VK_FORMAT_R16_UINT, 4442 VK_FORMAT_R16_SINT, 4443 VK_FORMAT_R16_SFLOAT, 4444 4445 VK_FORMAT_UNDEFINED 4446 }; 4447 const VkFormat compatibleFormats24Bit[] = 4448 { 4449 VK_FORMAT_R8G8B8_UNORM, 4450 VK_FORMAT_R8G8B8_SNORM, 4451 VK_FORMAT_R8G8B8_USCALED, 4452 VK_FORMAT_R8G8B8_SSCALED, 4453 VK_FORMAT_R8G8B8_UINT, 4454 VK_FORMAT_R8G8B8_SINT, 4455 VK_FORMAT_R8G8B8_SRGB, 4456 VK_FORMAT_B8G8R8_UNORM, 4457 VK_FORMAT_B8G8R8_SNORM, 4458 VK_FORMAT_B8G8R8_USCALED, 4459 VK_FORMAT_B8G8R8_SSCALED, 4460 VK_FORMAT_B8G8R8_UINT, 4461 VK_FORMAT_B8G8R8_SINT, 4462 VK_FORMAT_B8G8R8_SRGB, 4463 4464 VK_FORMAT_UNDEFINED 4465 }; 4466 const VkFormat compatibleFormats32Bit[] = 4467 { 4468 VK_FORMAT_R8G8B8A8_UNORM, 4469 VK_FORMAT_R8G8B8A8_SNORM, 4470 VK_FORMAT_R8G8B8A8_USCALED, 4471 VK_FORMAT_R8G8B8A8_SSCALED, 4472 VK_FORMAT_R8G8B8A8_UINT, 4473 VK_FORMAT_R8G8B8A8_SINT, 4474 VK_FORMAT_R8G8B8A8_SRGB, 4475 VK_FORMAT_B8G8R8A8_UNORM, 4476 VK_FORMAT_B8G8R8A8_SNORM, 4477 VK_FORMAT_B8G8R8A8_USCALED, 4478 VK_FORMAT_B8G8R8A8_SSCALED, 4479 VK_FORMAT_B8G8R8A8_UINT, 4480 VK_FORMAT_B8G8R8A8_SINT, 4481 VK_FORMAT_B8G8R8A8_SRGB, 4482 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 4483 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 4484 VK_FORMAT_A8B8G8R8_USCALED_PACK32, 4485 VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 4486 VK_FORMAT_A8B8G8R8_UINT_PACK32, 4487 VK_FORMAT_A8B8G8R8_SINT_PACK32, 4488 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 4489 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 4490 VK_FORMAT_A2R10G10B10_SNORM_PACK32, 4491 VK_FORMAT_A2R10G10B10_USCALED_PACK32, 4492 VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 4493 VK_FORMAT_A2R10G10B10_UINT_PACK32, 4494 VK_FORMAT_A2R10G10B10_SINT_PACK32, 4495 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 4496 VK_FORMAT_A2B10G10R10_SNORM_PACK32, 4497 VK_FORMAT_A2B10G10R10_USCALED_PACK32, 4498 VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 4499 VK_FORMAT_A2B10G10R10_UINT_PACK32, 4500 VK_FORMAT_A2B10G10R10_SINT_PACK32, 4501 VK_FORMAT_R16G16_UNORM, 4502 VK_FORMAT_R16G16_SNORM, 4503 VK_FORMAT_R16G16_USCALED, 4504 VK_FORMAT_R16G16_SSCALED, 4505 VK_FORMAT_R16G16_UINT, 4506 VK_FORMAT_R16G16_SINT, 4507 VK_FORMAT_R16G16_SFLOAT, 4508 VK_FORMAT_R32_UINT, 4509 VK_FORMAT_R32_SINT, 4510 VK_FORMAT_R32_SFLOAT, 4511 4512 VK_FORMAT_UNDEFINED 4513 }; 4514 const VkFormat compatibleFormats48Bit[] = 4515 { 4516 VK_FORMAT_R16G16B16_UNORM, 4517 VK_FORMAT_R16G16B16_SNORM, 4518 VK_FORMAT_R16G16B16_USCALED, 4519 VK_FORMAT_R16G16B16_SSCALED, 4520 VK_FORMAT_R16G16B16_UINT, 4521 VK_FORMAT_R16G16B16_SINT, 4522 VK_FORMAT_R16G16B16_SFLOAT, 4523 4524 VK_FORMAT_UNDEFINED 4525 }; 4526 const VkFormat compatibleFormats64Bit[] = 4527 { 4528 VK_FORMAT_R16G16B16A16_UNORM, 4529 VK_FORMAT_R16G16B16A16_SNORM, 4530 VK_FORMAT_R16G16B16A16_USCALED, 4531 VK_FORMAT_R16G16B16A16_SSCALED, 4532 VK_FORMAT_R16G16B16A16_UINT, 4533 VK_FORMAT_R16G16B16A16_SINT, 4534 VK_FORMAT_R16G16B16A16_SFLOAT, 4535 VK_FORMAT_R32G32_UINT, 4536 VK_FORMAT_R32G32_SINT, 4537 VK_FORMAT_R32G32_SFLOAT, 4538 VK_FORMAT_R64_UINT, 4539 VK_FORMAT_R64_SINT, 4540 VK_FORMAT_R64_SFLOAT, 4541 4542 VK_FORMAT_UNDEFINED 4543 }; 4544 const VkFormat compatibleFormats96Bit[] = 4545 { 4546 VK_FORMAT_R32G32B32_UINT, 4547 VK_FORMAT_R32G32B32_SINT, 4548 VK_FORMAT_R32G32B32_SFLOAT, 4549 4550 VK_FORMAT_UNDEFINED 4551 }; 4552 const VkFormat compatibleFormats128Bit[] = 4553 { 4554 VK_FORMAT_R32G32B32A32_UINT, 4555 VK_FORMAT_R32G32B32A32_SINT, 4556 VK_FORMAT_R32G32B32A32_SFLOAT, 4557 VK_FORMAT_R64G64_UINT, 4558 VK_FORMAT_R64G64_SINT, 4559 VK_FORMAT_R64G64_SFLOAT, 4560 4561 VK_FORMAT_UNDEFINED 4562 }; 4563 const VkFormat compatibleFormats192Bit[] = 4564 { 4565 VK_FORMAT_R64G64B64_UINT, 4566 VK_FORMAT_R64G64B64_SINT, 4567 VK_FORMAT_R64G64B64_SFLOAT, 4568 4569 VK_FORMAT_UNDEFINED 4570 }; 4571 const VkFormat compatibleFormats256Bit[] = 4572 { 4573 VK_FORMAT_R64G64B64A64_UINT, 4574 VK_FORMAT_R64G64B64A64_SINT, 4575 VK_FORMAT_R64G64B64A64_SFLOAT, 4576 4577 VK_FORMAT_UNDEFINED 4578 }; 4579 4580 const VkFormat* colorImageFormatsToTest[] = 4581 { 4582 compatibleFormats8Bit, 4583 compatibleFormats16Bit, 4584 compatibleFormats24Bit, 4585 compatibleFormats32Bit, 4586 compatibleFormats48Bit, 4587 compatibleFormats64Bit, 4588 compatibleFormats96Bit, 4589 compatibleFormats128Bit, 4590 compatibleFormats192Bit, 4591 compatibleFormats256Bit, 4592 }; 4593 4594 const VkFormat dedicatedAllocationImageToImageFormatsToTest[] = 4595 { 4596 // From compatibleFormats8Bit 4597 VK_FORMAT_R4G4_UNORM_PACK8, 4598 VK_FORMAT_R8_SRGB, 4599 4600 // From compatibleFormats16Bit 4601 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 4602 VK_FORMAT_R16_SFLOAT, 4603 4604 // From compatibleFormats24Bit 4605 VK_FORMAT_R8G8B8_UNORM, 4606 VK_FORMAT_B8G8R8_SRGB, 4607 4608 // From compatibleFormats32Bit 4609 VK_FORMAT_R8G8B8A8_UNORM, 4610 VK_FORMAT_R32_SFLOAT, 4611 4612 // From compatibleFormats48Bit 4613 VK_FORMAT_R16G16B16_UNORM, 4614 VK_FORMAT_R16G16B16_SFLOAT, 4615 4616 // From compatibleFormats64Bit 4617 VK_FORMAT_R16G16B16A16_UNORM, 4618 VK_FORMAT_R64_SFLOAT, 4619 4620 // From compatibleFormats96Bit 4621 VK_FORMAT_R32G32B32_UINT, 4622 VK_FORMAT_R32G32B32_SFLOAT, 4623 4624 // From compatibleFormats128Bit 4625 VK_FORMAT_R32G32B32A32_UINT, 4626 VK_FORMAT_R64G64_SFLOAT, 4627 4628 // From compatibleFormats192Bit 4629 VK_FORMAT_R64G64B64_UINT, 4630 VK_FORMAT_R64G64B64_SFLOAT, 4631 4632 // From compatibleFormats256Bit 4633 VK_FORMAT_R64G64B64A64_UINT, 4634 VK_FORMAT_R64G64B64A64_SFLOAT, 4635 }; 4636 4637 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4638 { 4639 TestParams params; 4640 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4641 params.src.image.extent = defaultExtent; 4642 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4643 params.dst.image.extent = defaultExtent; 4644 params.allocationKind = allocationKind; 4645 4646 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize) 4647 { 4648 const VkImageCopy testCopy = 4649 { 4650 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 4651 {0, 0, 0}, // VkOffset3D srcOffset; 4652 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 4653 {i, defaultSize - i - defaultFourthSize, 0}, // VkOffset3D dstOffset; 4654 {defaultFourthSize, defaultFourthSize, 1}, // VkExtent3D extent; 4655 }; 4656 4657 CopyRegion imageCopy; 4658 imageCopy.imageCopy = testCopy; 4659 4660 params.regions.push_back(imageCopy); 4661 } 4662 4663 if (allocationKind == ALLOCATION_KIND_DEDICATED) 4664 { 4665 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); 4666 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) 4667 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]); 4668 } 4669 4670 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); 4671 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) 4672 { 4673 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex]; 4674 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) 4675 { 4676 params.src.image.format = compatibleFormats[srcFormatIndex]; 4677 if (!isSupportedByFramework(params.src.image.format)) 4678 continue; 4679 4680 CopyColorTestParams testParams; 4681 testParams.params = params; 4682 testParams.compatibleFormats = compatibleFormats; 4683 4684 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format); 4685 addTestGroup(group, getFormatCaseName(params.src.image.format), description, addImageToImageAllFormatsColorSrcFormatTests, testParams); 4686 } 4687 } 4688 } 4689 4690 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params) 4691 { 4692 const VkImageLayout copySrcLayouts[] = 4693 { 4694 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 4695 VK_IMAGE_LAYOUT_GENERAL 4696 }; 4697 const VkImageLayout copyDstLayouts[] = 4698 { 4699 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 4700 VK_IMAGE_LAYOUT_GENERAL 4701 }; 4702 4703 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx) 4704 { 4705 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx]; 4706 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx) 4707 { 4708 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx]; 4709 4710 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" + 4711 getImageLayoutCaseName(params.dst.image.operationLayout); 4712 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) + 4713 " to " + getImageLayoutCaseName(params.dst.image.operationLayout); 4714 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params)); 4715 } 4716 } 4717 } 4718 4719 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4720 { 4721 const VkFormat depthAndStencilFormats[] = 4722 { 4723 VK_FORMAT_D16_UNORM, 4724 VK_FORMAT_X8_D24_UNORM_PACK32, 4725 VK_FORMAT_D32_SFLOAT, 4726 VK_FORMAT_S8_UINT, 4727 VK_FORMAT_D16_UNORM_S8_UINT, 4728 VK_FORMAT_D24_UNORM_S8_UINT, 4729 VK_FORMAT_D32_SFLOAT_S8_UINT, 4730 }; 4731 4732 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex) 4733 { 4734 TestParams params; 4735 params.src.image.imageType = VK_IMAGE_TYPE_2D; 4736 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 4737 params.src.image.extent = defaultExtent; 4738 params.dst.image.extent = defaultExtent; 4739 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex]; 4740 params.dst.image.format = params.src.image.format; 4741 params.allocationKind = allocationKind; 4742 4743 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u }; 4744 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u }; 4745 4746 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize) 4747 { 4748 CopyRegion copyRegion; 4749 const VkOffset3D srcOffset = {0, 0, 0}; 4750 const VkOffset3D dstOffset = {i, defaultSize - i - defaultFourthSize, 0}; 4751 const VkExtent3D extent = {defaultFourthSize, defaultFourthSize, 1}; 4752 4753 if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) 4754 { 4755 const VkImageCopy testCopy = 4756 { 4757 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; 4758 srcOffset, // VkOffset3D srcOffset; 4759 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; 4760 dstOffset, // VkOffset3D dstOffset; 4761 extent, // VkExtent3D extent; 4762 }; 4763 4764 copyRegion.imageCopy = testCopy; 4765 params.regions.push_back(copyRegion); 4766 } 4767 if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) 4768 { 4769 const VkImageCopy testCopy = 4770 { 4771 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; 4772 srcOffset, // VkOffset3D srcOffset; 4773 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; 4774 dstOffset, // VkOffset3D dstOffset; 4775 extent, // VkExtent3D extent; 4776 }; 4777 4778 copyRegion.imageCopy = testCopy; 4779 params.regions.push_back(copyRegion); 4780 } 4781 } 4782 4783 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format); 4784 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format); 4785 addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params); 4786 } 4787 } 4788 4789 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4790 { 4791 addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind); 4792 addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind); 4793 } 4794 4795 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 4796 { 4797 tcu::TestContext& testCtx = group->getTestContext(); 4798 4799 { 4800 TestParams params3DTo2D; 4801 const deUint32 slicesLayers = 16u; 4802 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D; 4803 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4804 params3DTo2D.src.image.extent = defaultHalfExtent; 4805 params3DTo2D.src.image.extent.depth = slicesLayers; 4806 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4807 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D; 4808 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 4809 params3DTo2D.dst.image.extent = defaultHalfExtent; 4810 params3DTo2D.dst.image.extent.depth = slicesLayers; 4811 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4812 params3DTo2D.allocationKind = allocationKind; 4813 4814 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) 4815 { 4816 const VkImageSubresourceLayers sourceLayer = 4817 { 4818 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4819 0u, // uint32_t mipLevel; 4820 0u, // uint32_t baseArrayLayer; 4821 1u // uint32_t layerCount; 4822 }; 4823 4824 const VkImageSubresourceLayers destinationLayer = 4825 { 4826 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4827 0u, // uint32_t mipLevel; 4828 slicesLayersNdx, // uint32_t baseArrayLayer; 4829 1u // uint32_t layerCount; 4830 }; 4831 4832 const VkImageCopy testCopy = 4833 { 4834 sourceLayer, // VkImageSubresourceLayers srcSubresource; 4835 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset; 4836 destinationLayer, // VkImageSubresourceLayers dstSubresource; 4837 {0, 0, 0}, // VkOffset3D dstOffset; 4838 defaultHalfExtent, // VkExtent3D extent; 4839 }; 4840 4841 CopyRegion imageCopy; 4842 imageCopy.imageCopy = testCopy; 4843 4844 params3DTo2D.regions.push_back(imageCopy); 4845 } 4846 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D)); 4847 } 4848 4849 { 4850 TestParams params2DTo3D; 4851 const deUint32 slicesLayers = 16u; 4852 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D; 4853 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4854 params2DTo3D.src.image.extent = defaultHalfExtent; 4855 params2DTo3D.src.image.extent.depth = slicesLayers; 4856 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4857 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D; 4858 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 4859 params2DTo3D.dst.image.extent = defaultHalfExtent; 4860 params2DTo3D.dst.image.extent.depth = slicesLayers; 4861 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4862 params2DTo3D.allocationKind = allocationKind; 4863 4864 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) 4865 { 4866 const VkImageSubresourceLayers sourceLayer = 4867 { 4868 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4869 0u, // uint32_t mipLevel; 4870 slicesLayersNdx, // uint32_t baseArrayLayer; 4871 1u // uint32_t layerCount; 4872 }; 4873 4874 const VkImageSubresourceLayers destinationLayer = 4875 { 4876 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4877 0u, // uint32_t mipLevel; 4878 0u, // uint32_t baseArrayLayer; 4879 1u // uint32_t layerCount; 4880 }; 4881 4882 const VkImageCopy testCopy = 4883 { 4884 sourceLayer, // VkImageSubresourceLayers srcSubresource; 4885 {0, 0, 0}, // VkOffset3D srcOffset; 4886 destinationLayer, // VkImageSubresourceLayers dstSubresource; 4887 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D dstOffset; 4888 defaultHalfExtent, // VkExtent3D extent; 4889 }; 4890 4891 CopyRegion imageCopy; 4892 imageCopy.imageCopy = testCopy; 4893 4894 params2DTo3D.regions.push_back(imageCopy); 4895 } 4896 4897 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D)); 4898 } 4899 4900 { 4901 TestParams params3DTo2D; 4902 const deUint32 slicesLayers = 16u; 4903 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D; 4904 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4905 params3DTo2D.src.image.extent = defaultHalfExtent; 4906 params3DTo2D.src.image.extent.depth = slicesLayers; 4907 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4908 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D; 4909 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 4910 params3DTo2D.dst.image.extent = defaultHalfExtent; 4911 params3DTo2D.dst.image.extent.depth = slicesLayers; 4912 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4913 params3DTo2D.allocationKind = allocationKind; 4914 4915 { 4916 const VkImageSubresourceLayers sourceLayer = 4917 { 4918 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4919 0u, // uint32_t mipLevel; 4920 0u, // uint32_t baseArrayLayer; 4921 1u // uint32_t layerCount; 4922 }; 4923 4924 const VkImageSubresourceLayers destinationLayer = 4925 { 4926 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4927 0u, // uint32_t mipLevel; 4928 0, // uint32_t baseArrayLayer; 4929 slicesLayers // uint32_t layerCount; 4930 }; 4931 4932 const VkImageCopy testCopy = 4933 { 4934 sourceLayer, // VkImageSubresourceLayers srcSubresource; 4935 {0, 0, 0}, // VkOffset3D srcOffset; 4936 destinationLayer, // VkImageSubresourceLayers dstSubresource; 4937 {0, 0, 0}, // VkOffset3D dstOffset; 4938 params3DTo2D.src.image.extent // VkExtent3D extent; 4939 }; 4940 4941 CopyRegion imageCopy; 4942 imageCopy.imageCopy = testCopy; 4943 4944 params3DTo2D.regions.push_back(imageCopy); 4945 } 4946 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D)); 4947 } 4948 4949 { 4950 TestParams params2DTo3D; 4951 const deUint32 slicesLayers = 16u; 4952 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D; 4953 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 4954 params2DTo3D.src.image.extent = defaultHalfExtent; 4955 params2DTo3D.src.image.extent.depth = slicesLayers; 4956 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 4957 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D; 4958 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 4959 params2DTo3D.dst.image.extent = defaultHalfExtent; 4960 params2DTo3D.dst.image.extent.depth = slicesLayers; 4961 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 4962 params2DTo3D.allocationKind = allocationKind; 4963 4964 { 4965 const VkImageSubresourceLayers sourceLayer = 4966 { 4967 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4968 0u, // uint32_t mipLevel; 4969 0u, // uint32_t baseArrayLayer; 4970 slicesLayers // uint32_t layerCount; 4971 }; 4972 4973 const VkImageSubresourceLayers destinationLayer = 4974 { 4975 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4976 0u, // uint32_t mipLevel; 4977 0u, // uint32_t baseArrayLayer; 4978 1u // uint32_t layerCount; 4979 }; 4980 4981 const VkImageCopy testCopy = 4982 { 4983 sourceLayer, // VkImageSubresourceLayers srcSubresource; 4984 {0, 0, 0}, // VkOffset3D srcOffset; 4985 destinationLayer, // VkImageSubresourceLayers dstSubresource; 4986 {0, 0, 0}, // VkOffset3D dstOffset; 4987 params2DTo3D.src.image.extent, // VkExtent3D extent; 4988 }; 4989 4990 CopyRegion imageCopy; 4991 imageCopy.imageCopy = testCopy; 4992 4993 params2DTo3D.regions.push_back(imageCopy); 4994 } 4995 4996 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D)); 4997 } 4998 4999 { 5000 TestParams params3DTo2D; 5001 const deUint32 slicesLayers = 16u; 5002 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D; 5003 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 5004 params3DTo2D.src.image.extent = defaultHalfExtent; 5005 params3DTo2D.src.image.extent.depth = slicesLayers; 5006 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5007 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D; 5008 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 5009 params3DTo2D.dst.image.extent = defaultHalfExtent; 5010 params3DTo2D.dst.image.extent.depth = slicesLayers; 5011 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5012 params3DTo2D.allocationKind = allocationKind; 5013 5014 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1; 5015 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ; 5016 5017 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) 5018 { 5019 const VkImageSubresourceLayers sourceLayer = 5020 { 5021 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 5022 0u, // uint32_t mipLevel; 5023 0u, // uint32_t baseArrayLayer; 5024 1u // uint32_t layerCount; 5025 }; 5026 5027 const VkImageSubresourceLayers destinationLayer = 5028 { 5029 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 5030 0u, // uint32_t mipLevel; 5031 slicesLayersNdx, // uint32_t baseArrayLayer; 5032 1u // uint32_t layerCount; 5033 }; 5034 5035 5036 const VkImageCopy testCopy = 5037 { 5038 sourceLayer, // VkImageSubresourceLayers srcSubresource; 5039 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset; 5040 destinationLayer, // VkImageSubresourceLayers dstSubresource; 5041 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset; 5042 { 5043 (defaultHalfExtent.width - regionWidth*slicesLayersNdx), 5044 (defaultHalfExtent.height - regionHeight*slicesLayersNdx), 5045 1 5046 } // VkExtent3D extent; 5047 }; 5048 5049 CopyRegion imageCopy; 5050 imageCopy.imageCopy = testCopy; 5051 params3DTo2D.regions.push_back(imageCopy); 5052 } 5053 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D)); 5054 } 5055 5056 { 5057 TestParams params2DTo3D; 5058 const deUint32 slicesLayers = 16u; 5059 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D; 5060 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; 5061 params2DTo3D.src.image.extent = defaultHalfExtent; 5062 params2DTo3D.src.image.extent.depth = slicesLayers; 5063 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5064 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D; 5065 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 5066 params2DTo3D.dst.image.extent = defaultHalfExtent; 5067 params2DTo3D.dst.image.extent.depth = slicesLayers; 5068 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5069 params2DTo3D.allocationKind = allocationKind; 5070 5071 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1; 5072 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ; 5073 5074 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) 5075 { 5076 const VkImageSubresourceLayers sourceLayer = 5077 { 5078 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 5079 0u, // uint32_t mipLevel; 5080 slicesLayersNdx, // uint32_t baseArrayLayer; 5081 1u // uint32_t layerCount; 5082 }; 5083 5084 const VkImageSubresourceLayers destinationLayer = 5085 { 5086 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 5087 0u, // uint32_t mipLevel; 5088 0u, // uint32_t baseArrayLayer; 5089 1u // uint32_t layerCount; 5090 }; 5091 5092 const VkImageCopy testCopy = 5093 { 5094 sourceLayer, // VkImageSubresourceLayers srcSubresource; 5095 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset; 5096 destinationLayer, // VkImageSubresourceLayers dstSubresource; 5097 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)}, // VkOffset3D dstOffset; 5098 { 5099 defaultHalfExtent.width - regionWidth*slicesLayersNdx, 5100 defaultHalfExtent.height - regionHeight*slicesLayersNdx, 5101 1 5102 } // VkExtent3D extent; 5103 }; 5104 5105 CopyRegion imageCopy; 5106 imageCopy.imageCopy = testCopy; 5107 5108 params2DTo3D.regions.push_back(imageCopy); 5109 } 5110 5111 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D)); 5112 } 5113 } 5114 5115 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5116 { 5117 addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind); 5118 addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind); 5119 addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind); 5120 } 5121 5122 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5123 { 5124 tcu::TestContext& testCtx = group->getTestContext(); 5125 5126 { 5127 TestParams params; 5128 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5129 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5130 params.src.image.extent = defaultExtent; 5131 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5132 params.dst.buffer.size = defaultSize * defaultSize; 5133 params.allocationKind = allocationKind; 5134 5135 const VkBufferImageCopy bufferImageCopy = 5136 { 5137 0u, // VkDeviceSize bufferOffset; 5138 0u, // uint32_t bufferRowLength; 5139 0u, // uint32_t bufferImageHeight; 5140 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; 5141 {0, 0, 0}, // VkOffset3D imageOffset; 5142 defaultExtent // VkExtent3D imageExtent; 5143 }; 5144 CopyRegion copyRegion; 5145 copyRegion.bufferImageCopy = bufferImageCopy; 5146 5147 params.regions.push_back(copyRegion); 5148 5149 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params)); 5150 } 5151 5152 { 5153 TestParams params; 5154 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5155 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5156 params.src.image.extent = defaultExtent; 5157 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5158 params.dst.buffer.size = defaultSize * defaultSize; 5159 params.allocationKind = allocationKind; 5160 5161 const VkBufferImageCopy bufferImageCopy = 5162 { 5163 defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset; 5164 0u, // uint32_t bufferRowLength; 5165 0u, // uint32_t bufferImageHeight; 5166 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; 5167 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset; 5168 defaultHalfExtent // VkExtent3D imageExtent; 5169 }; 5170 CopyRegion copyRegion; 5171 copyRegion.bufferImageCopy = bufferImageCopy; 5172 5173 params.regions.push_back(copyRegion); 5174 5175 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params)); 5176 } 5177 5178 { 5179 TestParams params; 5180 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5181 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5182 params.src.image.extent = defaultExtent; 5183 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5184 params.dst.buffer.size = defaultSize * defaultSize; 5185 params.allocationKind = allocationKind; 5186 5187 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format)); 5188 const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size; 5189 const VkDeviceSize offsetSize = pixelSize * defaultFourthSize * defaultFourthSize; 5190 deUint32 divisor = 1; 5191 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor) 5192 { 5193 const deUint32 bufferRowLength = defaultFourthSize; 5194 const deUint32 bufferImageHeight = defaultFourthSize; 5195 const VkExtent3D imageExtent = {defaultFourthSize / divisor, defaultFourthSize, 1}; 5196 DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width); 5197 DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height); 5198 DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize); 5199 5200 CopyRegion region; 5201 const VkBufferImageCopy bufferImageCopy = 5202 { 5203 offset, // VkDeviceSize bufferOffset; 5204 bufferRowLength, // uint32_t bufferRowLength; 5205 bufferImageHeight, // uint32_t bufferImageHeight; 5206 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; 5207 {0, 0, 0}, // VkOffset3D imageOffset; 5208 imageExtent // VkExtent3D imageExtent; 5209 }; 5210 region.bufferImageCopy = bufferImageCopy; 5211 params.regions.push_back(region); 5212 } 5213 5214 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params)); 5215 } 5216 } 5217 5218 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5219 { 5220 tcu::TestContext& testCtx = group->getTestContext(); 5221 5222 { 5223 TestParams params; 5224 params.src.buffer.size = defaultSize * defaultSize; 5225 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5226 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; 5227 params.dst.image.extent = defaultExtent; 5228 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5229 params.allocationKind = allocationKind; 5230 5231 const VkBufferImageCopy bufferImageCopy = 5232 { 5233 0u, // VkDeviceSize bufferOffset; 5234 0u, // uint32_t bufferRowLength; 5235 0u, // uint32_t bufferImageHeight; 5236 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; 5237 {0, 0, 0}, // VkOffset3D imageOffset; 5238 defaultExtent // VkExtent3D imageExtent; 5239 }; 5240 CopyRegion copyRegion; 5241 copyRegion.bufferImageCopy = bufferImageCopy; 5242 5243 params.regions.push_back(copyRegion); 5244 5245 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params)); 5246 } 5247 5248 { 5249 TestParams params; 5250 params.src.buffer.size = defaultSize * defaultSize; 5251 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5252 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5253 params.dst.image.extent = defaultExtent; 5254 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5255 params.allocationKind = allocationKind; 5256 5257 CopyRegion region; 5258 deUint32 divisor = 1; 5259 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++) 5260 { 5261 const VkBufferImageCopy bufferImageCopy = 5262 { 5263 0u, // VkDeviceSize bufferOffset; 5264 0u, // uint32_t bufferRowLength; 5265 0u, // uint32_t bufferImageHeight; 5266 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; 5267 {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset; 5268 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1} // VkExtent3D imageExtent; 5269 }; 5270 region.bufferImageCopy = bufferImageCopy; 5271 params.regions.push_back(region); 5272 } 5273 5274 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params)); 5275 } 5276 5277 { 5278 TestParams params; 5279 params.src.buffer.size = defaultSize * defaultSize; 5280 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5281 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5282 params.dst.image.extent = defaultExtent; 5283 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5284 params.allocationKind = allocationKind; 5285 5286 const VkBufferImageCopy bufferImageCopy = 5287 { 5288 defaultFourthSize, // VkDeviceSize bufferOffset; 5289 defaultHalfSize + defaultFourthSize, // uint32_t bufferRowLength; 5290 defaultHalfSize + defaultFourthSize, // uint32_t bufferImageHeight; 5291 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; 5292 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset; 5293 defaultHalfExtent // VkExtent3D imageExtent; 5294 }; 5295 CopyRegion copyRegion; 5296 copyRegion.bufferImageCopy = bufferImageCopy; 5297 5298 params.regions.push_back(copyRegion); 5299 5300 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params)); 5301 } 5302 } 5303 5304 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5305 { 5306 tcu::TestContext& testCtx = group->getTestContext(); 5307 5308 { 5309 TestParams params; 5310 params.src.buffer.size = defaultSize; 5311 params.dst.buffer.size = defaultSize; 5312 params.allocationKind = allocationKind; 5313 5314 const VkBufferCopy bufferCopy = 5315 { 5316 0u, // VkDeviceSize srcOffset; 5317 0u, // VkDeviceSize dstOffset; 5318 defaultSize, // VkDeviceSize size; 5319 }; 5320 5321 CopyRegion copyRegion; 5322 copyRegion.bufferCopy = bufferCopy; 5323 params.regions.push_back(copyRegion); 5324 5325 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params)); 5326 } 5327 5328 // Filter is VK_FILTER_NEAREST. 5329 { 5330 TestParams params; 5331 params.src.buffer.size = defaultFourthSize; 5332 params.dst.buffer.size = defaultFourthSize; 5333 params.allocationKind = allocationKind; 5334 5335 const VkBufferCopy bufferCopy = 5336 { 5337 12u, // VkDeviceSize srcOffset; 5338 4u, // VkDeviceSize dstOffset; 5339 1u, // VkDeviceSize size; 5340 }; 5341 5342 CopyRegion copyRegion; 5343 copyRegion.bufferCopy = bufferCopy; 5344 params.regions.push_back(copyRegion); 5345 5346 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params)); 5347 } 5348 5349 { 5350 const deUint32 size = 16; 5351 TestParams params; 5352 params.src.buffer.size = size; 5353 params.dst.buffer.size = size * (size + 1); 5354 params.allocationKind = allocationKind; 5355 5356 // Copy region with size 1..size 5357 for (unsigned int i = 1; i <= size; i++) 5358 { 5359 const VkBufferCopy bufferCopy = 5360 { 5361 0, // VkDeviceSize srcOffset; 5362 i * size, // VkDeviceSize dstOffset; 5363 i, // VkDeviceSize size; 5364 }; 5365 5366 CopyRegion copyRegion; 5367 copyRegion.bufferCopy = bufferCopy; 5368 params.regions.push_back(copyRegion); 5369 } 5370 5371 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params)); 5372 } 5373 } 5374 5375 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5376 { 5377 tcu::TestContext& testCtx = group->getTestContext(); 5378 TestParams params; 5379 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5380 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5381 params.src.image.extent = defaultExtent; 5382 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5383 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5384 params.dst.image.extent = defaultExtent; 5385 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5386 params.allocationKind = allocationKind; 5387 5388 { 5389 const VkImageBlit imageBlit = 5390 { 5391 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5392 { 5393 { 0, 0, 0 }, 5394 { defaultSize, defaultSize, 1 } 5395 }, // VkOffset3D srcOffsets[2]; 5396 5397 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5398 { 5399 { 0, 0, 0 }, 5400 { defaultSize, defaultSize, 1 } 5401 } // VkOffset3D dstOffset[2]; 5402 }; 5403 5404 CopyRegion region; 5405 region.imageBlit = imageBlit; 5406 params.regions.push_back(region); 5407 } 5408 5409 // Filter is VK_FILTER_NEAREST. 5410 { 5411 params.filter = VK_FILTER_NEAREST; 5412 const std::string description = "Nearest filter"; 5413 5414 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5415 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5416 5417 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5418 const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)"); 5419 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5420 5421 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5422 const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5423 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5424 } 5425 5426 // Filter is VK_FILTER_LINEAR. 5427 { 5428 params.filter = VK_FILTER_LINEAR; 5429 const std::string description = "Linear filter"; 5430 5431 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5432 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5433 5434 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5435 const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)"); 5436 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5437 5438 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5439 const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5440 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5441 } 5442 } 5443 5444 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5445 { 5446 tcu::TestContext& testCtx = group->getTestContext(); 5447 TestParams params; 5448 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5449 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5450 params.src.image.extent = defaultExtent; 5451 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5452 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5453 params.dst.image.extent = defaultExtent; 5454 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5455 params.allocationKind = allocationKind; 5456 5457 { 5458 const VkImageBlit imageBlit = 5459 { 5460 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5461 { 5462 {0, 0, 0}, 5463 {defaultSize, defaultSize, 1} 5464 }, // VkOffset3D srcOffsets[2]; 5465 5466 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5467 { 5468 {defaultSize, defaultSize, 0}, 5469 {0, 0, 1} 5470 } // VkOffset3D dstOffset[2]; 5471 }; 5472 5473 CopyRegion region; 5474 region.imageBlit = imageBlit; 5475 params.regions.push_back(region); 5476 } 5477 5478 // Filter is VK_FILTER_NEAREST. 5479 { 5480 params.filter = VK_FILTER_NEAREST; 5481 const std::string description = "Nearest filter"; 5482 5483 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5484 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5485 5486 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5487 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5488 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5489 5490 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5491 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5492 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5493 } 5494 5495 // Filter is VK_FILTER_LINEAR. 5496 { 5497 params.filter = VK_FILTER_LINEAR; 5498 const std::string description = "Linear filter"; 5499 5500 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5501 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5502 5503 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5504 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5505 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5506 5507 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5508 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5509 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5510 } 5511 } 5512 5513 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5514 { 5515 tcu::TestContext& testCtx = group->getTestContext(); 5516 TestParams params; 5517 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5518 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5519 params.src.image.extent = defaultExtent; 5520 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5521 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5522 params.dst.image.extent = defaultExtent; 5523 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5524 params.allocationKind = allocationKind; 5525 5526 { 5527 const VkImageBlit imageBlit = 5528 { 5529 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5530 { 5531 {0, 0, 0}, 5532 {defaultSize, defaultSize, 1} 5533 }, // VkOffset3D srcOffsets[2]; 5534 5535 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5536 { 5537 {defaultSize, 0, 0}, 5538 {0, defaultSize, 1} 5539 } // VkOffset3D dstOffset[2]; 5540 }; 5541 5542 CopyRegion region; 5543 region.imageBlit = imageBlit; 5544 params.regions.push_back(region); 5545 } 5546 5547 // Filter is VK_FILTER_NEAREST. 5548 { 5549 params.filter = VK_FILTER_NEAREST; 5550 const std::string description = "Nearest filter"; 5551 5552 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5553 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5554 5555 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5556 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5557 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5558 5559 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5560 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5561 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5562 } 5563 5564 // Filter is VK_FILTER_LINEAR. 5565 { 5566 params.filter = VK_FILTER_LINEAR; 5567 const std::string description = "Linear filter"; 5568 5569 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5570 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5571 5572 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5573 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5574 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5575 5576 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5577 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5578 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5579 } 5580 } 5581 5582 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5583 { 5584 tcu::TestContext& testCtx = group->getTestContext(); 5585 TestParams params; 5586 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5587 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5588 params.src.image.extent = defaultExtent; 5589 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5590 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5591 params.dst.image.extent = defaultExtent; 5592 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5593 params.allocationKind = allocationKind; 5594 5595 { 5596 const VkImageBlit imageBlit = 5597 { 5598 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5599 { 5600 {0, 0, 0}, 5601 {defaultSize, defaultSize, 1} 5602 }, // VkOffset3D srcOffsets[2]; 5603 5604 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5605 { 5606 {0, defaultSize, 0}, 5607 {defaultSize, 0, 1} 5608 } // VkOffset3D dstOffset[2]; 5609 }; 5610 5611 CopyRegion region; 5612 region.imageBlit = imageBlit; 5613 params.regions.push_back(region); 5614 } 5615 5616 // Filter is VK_FILTER_NEAREST. 5617 { 5618 params.filter = VK_FILTER_NEAREST; 5619 const std::string description = "Nearest filter"; 5620 5621 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5622 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5623 5624 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5625 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5626 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5627 5628 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5629 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5630 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5631 } 5632 5633 // Filter is VK_FILTER_LINEAR. 5634 { 5635 params.filter = VK_FILTER_LINEAR; 5636 const std::string description = "Linear filter"; 5637 5638 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5639 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5640 5641 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5642 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5643 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5644 5645 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5646 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5647 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5648 } 5649 } 5650 5651 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5652 { 5653 tcu::TestContext& testCtx = group->getTestContext(); 5654 TestParams params; 5655 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5656 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5657 params.src.image.extent = defaultExtent; 5658 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5659 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5660 params.dst.image.extent = defaultExtent; 5661 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5662 params.allocationKind = allocationKind; 5663 5664 // No mirroring. 5665 { 5666 const VkImageBlit imageBlit = 5667 { 5668 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5669 { 5670 {0, 0, 0}, 5671 {defaultHalfSize, defaultHalfSize, 1} 5672 }, // VkOffset3D srcOffsets[2]; 5673 5674 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5675 { 5676 {0, 0, 0}, 5677 {defaultHalfSize, defaultHalfSize, 1} 5678 } // VkOffset3D dstOffset[2]; 5679 }; 5680 5681 CopyRegion region; 5682 region.imageBlit = imageBlit; 5683 params.regions.push_back(region); 5684 } 5685 5686 // Flipping y coordinates. 5687 { 5688 const VkImageBlit imageBlit = 5689 { 5690 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5691 { 5692 {defaultHalfSize, 0, 0}, 5693 {defaultSize, defaultHalfSize, 1} 5694 }, // VkOffset3D srcOffsets[2]; 5695 5696 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5697 { 5698 {defaultHalfSize, defaultHalfSize, 0}, 5699 {defaultSize, 0, 1} 5700 } // VkOffset3D dstOffset[2]; 5701 }; 5702 CopyRegion region; 5703 region.imageBlit = imageBlit; 5704 params.regions.push_back(region); 5705 } 5706 5707 // Flipping x coordinates. 5708 { 5709 const VkImageBlit imageBlit = 5710 { 5711 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5712 { 5713 {0, defaultHalfSize, 0}, 5714 {defaultHalfSize, defaultSize, 1} 5715 }, // VkOffset3D srcOffsets[2]; 5716 5717 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5718 { 5719 {defaultHalfSize, defaultHalfSize, 0}, 5720 {0, defaultSize, 1} 5721 } // VkOffset3D dstOffset[2]; 5722 }; 5723 5724 CopyRegion region; 5725 region.imageBlit = imageBlit; 5726 params.regions.push_back(region); 5727 } 5728 5729 // Flipping x and y coordinates. 5730 { 5731 const VkImageBlit imageBlit = 5732 { 5733 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5734 { 5735 {defaultHalfSize, defaultHalfSize, 0}, 5736 {defaultSize, defaultSize, 1} 5737 }, // VkOffset3D srcOffsets[2]; 5738 5739 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5740 { 5741 {defaultSize, defaultSize, 0}, 5742 {defaultHalfSize, defaultHalfSize, 1} 5743 } // VkOffset3D dstOffset[2]; 5744 }; 5745 5746 CopyRegion region; 5747 region.imageBlit = imageBlit; 5748 params.regions.push_back(region); 5749 } 5750 5751 // Filter is VK_FILTER_NEAREST. 5752 { 5753 params.filter = VK_FILTER_NEAREST; 5754 const std::string description = "Nearest filter"; 5755 5756 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5757 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5758 5759 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5760 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5761 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5762 5763 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5764 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5765 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5766 } 5767 5768 // Filter is VK_FILTER_LINEAR. 5769 { 5770 params.filter = VK_FILTER_LINEAR; 5771 const std::string description = "Linear filter"; 5772 5773 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5774 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5775 5776 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5777 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5778 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5779 5780 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5781 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5782 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5783 } 5784 } 5785 5786 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5787 { 5788 tcu::TestContext& testCtx = group->getTestContext(); 5789 TestParams params; 5790 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5791 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5792 params.src.image.extent = defaultExtent; 5793 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5794 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5795 params.dst.image.extent = defaultHalfExtent; 5796 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5797 params.allocationKind = allocationKind; 5798 5799 { 5800 const VkImageBlit imageBlit = 5801 { 5802 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5803 { 5804 {0, 0, 0}, 5805 {defaultSize, defaultSize, 1} 5806 }, // VkOffset3D srcOffsets[2]; 5807 5808 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5809 { 5810 {0, 0, 0}, 5811 {defaultHalfSize, defaultHalfSize, 1} 5812 } // VkOffset3D dstOffset[2]; 5813 }; 5814 5815 CopyRegion region; 5816 region.imageBlit = imageBlit; 5817 params.regions.push_back(region); 5818 } 5819 5820 // Filter is VK_FILTER_NEAREST. 5821 { 5822 params.filter = VK_FILTER_NEAREST; 5823 const std::string description = "Nearest filter"; 5824 5825 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5826 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5827 5828 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5829 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5830 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5831 5832 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5833 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5834 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5835 } 5836 5837 // Filter is VK_FILTER_LINEAR. 5838 { 5839 params.filter = VK_FILTER_LINEAR; 5840 const std::string description = "Linear filter"; 5841 5842 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5843 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5844 5845 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5846 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" ); 5847 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5848 5849 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5850 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5851 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5852 } 5853 } 5854 5855 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5856 { 5857 tcu::TestContext& testCtx = group->getTestContext(); 5858 TestParams params; 5859 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5860 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5861 params.src.image.extent = defaultHalfExtent; 5862 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5863 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5864 params.dst.image.extent = defaultExtent; 5865 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5866 params.allocationKind = allocationKind; 5867 5868 { 5869 const VkImageBlit imageBlit = 5870 { 5871 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5872 { 5873 {0, 0, 0}, 5874 {defaultHalfSize, defaultHalfSize, 1} 5875 }, // VkOffset3D srcOffsets[2]; 5876 5877 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5878 { 5879 {0, 0, 0}, 5880 {defaultSize, defaultSize, 1} 5881 } // VkOffset3D dstOffset[2]; 5882 }; 5883 5884 CopyRegion region; 5885 region.imageBlit = imageBlit; 5886 params.regions.push_back(region); 5887 } 5888 5889 // Filter is VK_FILTER_NEAREST. 5890 { 5891 params.filter = VK_FILTER_NEAREST; 5892 const std::string description = "Nearest filter"; 5893 5894 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5895 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5896 5897 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5898 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5899 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5900 5901 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5902 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5903 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5904 } 5905 5906 // Filter is VK_FILTER_LINEAR. 5907 { 5908 params.filter = VK_FILTER_LINEAR; 5909 const std::string description = "Linear filter"; 5910 5911 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5912 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5913 5914 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5915 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5916 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5917 5918 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5919 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5920 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5921 } 5922 } 5923 5924 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5925 { 5926 tcu::TestContext& testCtx = group->getTestContext(); 5927 TestParams params; 5928 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5929 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5930 params.src.image.extent = defaultExtent; 5931 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 5932 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 5933 params.dst.image.extent = defaultExtent; 5934 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 5935 params.allocationKind = allocationKind; 5936 5937 { 5938 const VkImageBlit imageBlit = 5939 { 5940 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 5941 { 5942 {defaultFourthSize, defaultFourthSize, 0}, 5943 {defaultFourthSize*3, defaultFourthSize*3, 1} 5944 }, // VkOffset3D srcOffsets[2]; 5945 5946 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 5947 { 5948 {0, 0, 0}, 5949 {defaultSize, defaultSize, 1} 5950 } // VkOffset3D dstOffset[2]; 5951 }; 5952 5953 CopyRegion region; 5954 region.imageBlit = imageBlit; 5955 params.regions.push_back(region); 5956 } 5957 5958 // Filter is VK_FILTER_NEAREST. 5959 { 5960 params.filter = VK_FILTER_NEAREST; 5961 const std::string description = "Nearest filter"; 5962 5963 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5964 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 5965 5966 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5967 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5968 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 5969 5970 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5971 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5972 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 5973 } 5974 5975 // Filter is VK_FILTER_LINEAR. 5976 { 5977 params.filter = VK_FILTER_LINEAR; 5978 const std::string description = "Linear filter"; 5979 5980 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5981 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 5982 5983 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 5984 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 5985 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 5986 5987 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 5988 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 5989 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 5990 } 5991 } 5992 5993 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 5994 { 5995 tcu::TestContext& testCtx = group->getTestContext(); 5996 TestParams params; 5997 params.src.image.imageType = VK_IMAGE_TYPE_2D; 5998 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 5999 params.src.image.extent = defaultExtent; 6000 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 6001 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6002 params.dst.image.extent = defaultExtent; 6003 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 6004 params.allocationKind = allocationKind; 6005 6006 { 6007 CopyRegion region; 6008 for (int i = 0; i < defaultSize; i += defaultFourthSize) 6009 { 6010 const VkImageBlit imageBlit = 6011 { 6012 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 6013 { 6014 {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0}, 6015 {defaultSize - i, defaultSize - i, 1} 6016 }, // VkOffset3D srcOffsets[2]; 6017 6018 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 6019 { 6020 {i, i, 0}, 6021 {i + defaultFourthSize, i + defaultFourthSize, 1} 6022 } // VkOffset3D dstOffset[2]; 6023 }; 6024 region.imageBlit = imageBlit; 6025 params.regions.push_back(region); 6026 } 6027 } 6028 6029 // Filter is VK_FILTER_NEAREST. 6030 { 6031 params.filter = VK_FILTER_NEAREST; 6032 const std::string description = "Nearest filter"; 6033 6034 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6035 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params)); 6036 6037 6038 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 6039 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 6040 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); 6041 6042 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 6043 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 6044 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); 6045 } 6046 6047 // Filter is VK_FILTER_LINEAR. 6048 { 6049 params.filter = VK_FILTER_LINEAR; 6050 const std::string description = "Linear filter"; 6051 6052 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6053 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params)); 6054 6055 params.dst.image.format = VK_FORMAT_R32_SFLOAT; 6056 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); 6057 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); 6058 6059 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; 6060 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); 6061 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); 6062 } 6063 } 6064 6065 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6066 { 6067 addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, allocationKind); 6068 addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, allocationKind); 6069 addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, allocationKind); 6070 addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, allocationKind); 6071 addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, allocationKind); 6072 addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, allocationKind); 6073 addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, allocationKind); 6074 addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, allocationKind); 6075 addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, allocationKind); 6076 } 6077 6078 struct BlitColorTestParams 6079 { 6080 TestParams params; 6081 const VkFormat* compatibleFormats; 6082 bool onlyNearest; 6083 }; 6084 6085 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams) 6086 { 6087 bool result = true; 6088 6089 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED) 6090 { 6091 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty()); 6092 6093 result = 6094 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) || 6095 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format); 6096 } 6097 6098 return result; 6099 } 6100 6101 6102 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams) 6103 { 6104 tcu::TestContext& testCtx = group->getTestContext(); 6105 6106 const VkImageLayout blitSrcLayouts[] = 6107 { 6108 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 6109 VK_IMAGE_LAYOUT_GENERAL 6110 }; 6111 const VkImageLayout blitDstLayouts[] = 6112 { 6113 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 6114 VK_IMAGE_LAYOUT_GENERAL 6115 }; 6116 6117 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx) 6118 { 6119 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx]; 6120 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx) 6121 { 6122 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx]; 6123 6124 testParams.params.filter = VK_FILTER_NEAREST; 6125 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + 6126 getImageLayoutCaseName(testParams.params.dst.image.operationLayout); 6127 const std::string description = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + 6128 " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout); 6129 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params)); 6130 6131 if (!testParams.onlyNearest) 6132 { 6133 testParams.params.filter = VK_FILTER_LINEAR; 6134 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params)); 6135 } 6136 } 6137 } 6138 } 6139 6140 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams) 6141 { 6142 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex) 6143 { 6144 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex]; 6145 if (!isSupportedByFramework(testParams.params.dst.image.format)) 6146 continue; 6147 6148 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams)) 6149 continue; 6150 6151 const std::string description = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format); 6152 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams); 6153 } 6154 } 6155 6156 const VkFormat compatibleFormatsUInts[] = 6157 { 6158 VK_FORMAT_R8_UINT, 6159 VK_FORMAT_R8G8_UINT, 6160 VK_FORMAT_R8G8B8_UINT, 6161 VK_FORMAT_B8G8R8_UINT, 6162 VK_FORMAT_R8G8B8A8_UINT, 6163 VK_FORMAT_B8G8R8A8_UINT, 6164 VK_FORMAT_A8B8G8R8_UINT_PACK32, 6165 VK_FORMAT_A2R10G10B10_UINT_PACK32, 6166 VK_FORMAT_A2B10G10R10_UINT_PACK32, 6167 VK_FORMAT_R16_UINT, 6168 VK_FORMAT_R16G16_UINT, 6169 VK_FORMAT_R16G16B16_UINT, 6170 VK_FORMAT_R16G16B16A16_UINT, 6171 VK_FORMAT_R32_UINT, 6172 VK_FORMAT_R32G32_UINT, 6173 VK_FORMAT_R32G32B32_UINT, 6174 VK_FORMAT_R32G32B32A32_UINT, 6175 VK_FORMAT_R64_UINT, 6176 VK_FORMAT_R64G64_UINT, 6177 VK_FORMAT_R64G64B64_UINT, 6178 VK_FORMAT_R64G64B64A64_UINT, 6179 6180 VK_FORMAT_UNDEFINED 6181 }; 6182 const VkFormat compatibleFormatsSInts[] = 6183 { 6184 VK_FORMAT_R8_SINT, 6185 VK_FORMAT_R8G8_SINT, 6186 VK_FORMAT_R8G8B8_SINT, 6187 VK_FORMAT_B8G8R8_SINT, 6188 VK_FORMAT_R8G8B8A8_SINT, 6189 VK_FORMAT_B8G8R8A8_SINT, 6190 VK_FORMAT_A8B8G8R8_SINT_PACK32, 6191 VK_FORMAT_A2R10G10B10_SINT_PACK32, 6192 VK_FORMAT_A2B10G10R10_SINT_PACK32, 6193 VK_FORMAT_R16_SINT, 6194 VK_FORMAT_R16G16_SINT, 6195 VK_FORMAT_R16G16B16_SINT, 6196 VK_FORMAT_R16G16B16A16_SINT, 6197 VK_FORMAT_R32_SINT, 6198 VK_FORMAT_R32G32_SINT, 6199 VK_FORMAT_R32G32B32_SINT, 6200 VK_FORMAT_R32G32B32A32_SINT, 6201 VK_FORMAT_R64_SINT, 6202 VK_FORMAT_R64G64_SINT, 6203 VK_FORMAT_R64G64B64_SINT, 6204 VK_FORMAT_R64G64B64A64_SINT, 6205 6206 VK_FORMAT_UNDEFINED 6207 }; 6208 const VkFormat compatibleFormatsFloats[] = 6209 { 6210 VK_FORMAT_R4G4_UNORM_PACK8, 6211 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 6212 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 6213 VK_FORMAT_R5G6B5_UNORM_PACK16, 6214 VK_FORMAT_B5G6R5_UNORM_PACK16, 6215 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 6216 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 6217 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 6218 VK_FORMAT_R8_UNORM, 6219 VK_FORMAT_R8_SNORM, 6220 VK_FORMAT_R8_USCALED, 6221 VK_FORMAT_R8_SSCALED, 6222 VK_FORMAT_R8G8_UNORM, 6223 VK_FORMAT_R8G8_SNORM, 6224 VK_FORMAT_R8G8_USCALED, 6225 VK_FORMAT_R8G8_SSCALED, 6226 VK_FORMAT_R8G8B8_UNORM, 6227 VK_FORMAT_R8G8B8_SNORM, 6228 VK_FORMAT_R8G8B8_USCALED, 6229 VK_FORMAT_R8G8B8_SSCALED, 6230 VK_FORMAT_B8G8R8_UNORM, 6231 VK_FORMAT_B8G8R8_SNORM, 6232 VK_FORMAT_B8G8R8_USCALED, 6233 VK_FORMAT_B8G8R8_SSCALED, 6234 VK_FORMAT_R8G8B8A8_UNORM, 6235 VK_FORMAT_R8G8B8A8_SNORM, 6236 VK_FORMAT_R8G8B8A8_USCALED, 6237 VK_FORMAT_R8G8B8A8_SSCALED, 6238 VK_FORMAT_B8G8R8A8_UNORM, 6239 VK_FORMAT_B8G8R8A8_SNORM, 6240 VK_FORMAT_B8G8R8A8_USCALED, 6241 VK_FORMAT_B8G8R8A8_SSCALED, 6242 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 6243 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 6244 VK_FORMAT_A8B8G8R8_USCALED_PACK32, 6245 VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 6246 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 6247 VK_FORMAT_A2R10G10B10_SNORM_PACK32, 6248 VK_FORMAT_A2R10G10B10_USCALED_PACK32, 6249 VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 6250 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 6251 VK_FORMAT_A2B10G10R10_SNORM_PACK32, 6252 VK_FORMAT_A2B10G10R10_USCALED_PACK32, 6253 VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 6254 VK_FORMAT_R16_UNORM, 6255 VK_FORMAT_R16_SNORM, 6256 VK_FORMAT_R16_USCALED, 6257 VK_FORMAT_R16_SSCALED, 6258 VK_FORMAT_R16_SFLOAT, 6259 VK_FORMAT_R16G16_UNORM, 6260 VK_FORMAT_R16G16_SNORM, 6261 VK_FORMAT_R16G16_USCALED, 6262 VK_FORMAT_R16G16_SSCALED, 6263 VK_FORMAT_R16G16_SFLOAT, 6264 VK_FORMAT_R16G16B16_UNORM, 6265 VK_FORMAT_R16G16B16_SNORM, 6266 VK_FORMAT_R16G16B16_USCALED, 6267 VK_FORMAT_R16G16B16_SSCALED, 6268 VK_FORMAT_R16G16B16_SFLOAT, 6269 VK_FORMAT_R16G16B16A16_UNORM, 6270 VK_FORMAT_R16G16B16A16_SNORM, 6271 VK_FORMAT_R16G16B16A16_USCALED, 6272 VK_FORMAT_R16G16B16A16_SSCALED, 6273 VK_FORMAT_R16G16B16A16_SFLOAT, 6274 VK_FORMAT_R32_SFLOAT, 6275 VK_FORMAT_R32G32_SFLOAT, 6276 VK_FORMAT_R32G32B32_SFLOAT, 6277 VK_FORMAT_R32G32B32A32_SFLOAT, 6278 VK_FORMAT_R64_SFLOAT, 6279 VK_FORMAT_R64G64_SFLOAT, 6280 VK_FORMAT_R64G64B64_SFLOAT, 6281 VK_FORMAT_R64G64B64A64_SFLOAT, 6282 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 6283 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 6284 // VK_FORMAT_BC1_RGB_UNORM_BLOCK, 6285 // VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 6286 // VK_FORMAT_BC2_UNORM_BLOCK, 6287 // VK_FORMAT_BC3_UNORM_BLOCK, 6288 // VK_FORMAT_BC4_UNORM_BLOCK, 6289 // VK_FORMAT_BC4_SNORM_BLOCK, 6290 // VK_FORMAT_BC5_UNORM_BLOCK, 6291 // VK_FORMAT_BC5_SNORM_BLOCK, 6292 // VK_FORMAT_BC6H_UFLOAT_BLOCK, 6293 // VK_FORMAT_BC6H_SFLOAT_BLOCK, 6294 // VK_FORMAT_BC7_UNORM_BLOCK, 6295 // VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, 6296 // VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, 6297 // VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, 6298 // VK_FORMAT_EAC_R11_UNORM_BLOCK, 6299 // VK_FORMAT_EAC_R11_SNORM_BLOCK, 6300 // VK_FORMAT_EAC_R11G11_UNORM_BLOCK, 6301 // VK_FORMAT_EAC_R11G11_SNORM_BLOCK, 6302 // VK_FORMAT_ASTC_4x4_UNORM_BLOCK, 6303 // VK_FORMAT_ASTC_5x4_UNORM_BLOCK, 6304 // VK_FORMAT_ASTC_5x5_UNORM_BLOCK, 6305 // VK_FORMAT_ASTC_6x5_UNORM_BLOCK, 6306 // VK_FORMAT_ASTC_6x6_UNORM_BLOCK, 6307 // VK_FORMAT_ASTC_8x5_UNORM_BLOCK, 6308 // VK_FORMAT_ASTC_8x6_UNORM_BLOCK, 6309 // VK_FORMAT_ASTC_8x8_UNORM_BLOCK, 6310 // VK_FORMAT_ASTC_10x5_UNORM_BLOCK, 6311 // VK_FORMAT_ASTC_10x6_UNORM_BLOCK, 6312 // VK_FORMAT_ASTC_10x8_UNORM_BLOCK, 6313 // VK_FORMAT_ASTC_10x10_UNORM_BLOCK, 6314 // VK_FORMAT_ASTC_12x10_UNORM_BLOCK, 6315 // VK_FORMAT_ASTC_12x12_UNORM_BLOCK, 6316 6317 VK_FORMAT_UNDEFINED 6318 }; 6319 const VkFormat compatibleFormatsSrgb[] = 6320 { 6321 VK_FORMAT_R8_SRGB, 6322 VK_FORMAT_R8G8_SRGB, 6323 VK_FORMAT_R8G8B8_SRGB, 6324 VK_FORMAT_B8G8R8_SRGB, 6325 VK_FORMAT_R8G8B8A8_SRGB, 6326 VK_FORMAT_B8G8R8A8_SRGB, 6327 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 6328 // VK_FORMAT_BC1_RGB_SRGB_BLOCK, 6329 // VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 6330 // VK_FORMAT_BC2_SRGB_BLOCK, 6331 // VK_FORMAT_BC3_SRGB_BLOCK, 6332 // VK_FORMAT_BC7_SRGB_BLOCK, 6333 // VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, 6334 // VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, 6335 // VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, 6336 // VK_FORMAT_ASTC_4x4_SRGB_BLOCK, 6337 // VK_FORMAT_ASTC_5x4_SRGB_BLOCK, 6338 // VK_FORMAT_ASTC_5x5_SRGB_BLOCK, 6339 // VK_FORMAT_ASTC_6x5_SRGB_BLOCK, 6340 // VK_FORMAT_ASTC_6x6_SRGB_BLOCK, 6341 // VK_FORMAT_ASTC_8x5_SRGB_BLOCK, 6342 // VK_FORMAT_ASTC_8x6_SRGB_BLOCK, 6343 // VK_FORMAT_ASTC_8x8_SRGB_BLOCK, 6344 // VK_FORMAT_ASTC_10x5_SRGB_BLOCK, 6345 // VK_FORMAT_ASTC_10x6_SRGB_BLOCK, 6346 // VK_FORMAT_ASTC_10x8_SRGB_BLOCK, 6347 // VK_FORMAT_ASTC_10x10_SRGB_BLOCK, 6348 // VK_FORMAT_ASTC_12x10_SRGB_BLOCK, 6349 // VK_FORMAT_ASTC_12x12_SRGB_BLOCK, 6350 6351 VK_FORMAT_UNDEFINED 6352 }; 6353 6354 const VkFormat dedicatedAllocationBlittingFormatsToTest[] = 6355 { 6356 // compatibleFormatsUInts 6357 VK_FORMAT_R8_UINT, 6358 VK_FORMAT_R64G64B64A64_UINT, 6359 6360 // compatibleFormatsSInts 6361 VK_FORMAT_R8_SINT, 6362 VK_FORMAT_R64G64B64A64_SINT, 6363 6364 // compatibleFormatsFloats 6365 VK_FORMAT_R4G4_UNORM_PACK8, 6366 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 6367 6368 // compatibleFormatsSrgb 6369 VK_FORMAT_R8_SRGB, 6370 VK_FORMAT_A8B8G8R8_SRGB_PACK32, 6371 }; 6372 6373 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6374 { 6375 const struct { 6376 const VkFormat* compatibleFormats; 6377 const bool onlyNearest; 6378 } colorImageFormatsToTestBlit[] = 6379 { 6380 { compatibleFormatsUInts, true }, 6381 { compatibleFormatsSInts, true }, 6382 { compatibleFormatsFloats, false }, 6383 { compatibleFormatsSrgb, false }, 6384 }; 6385 6386 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit); 6387 6388 TestParams params; 6389 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6390 params.src.image.extent = defaultExtent; 6391 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6392 params.dst.image.extent = defaultExtent; 6393 params.allocationKind = allocationKind; 6394 6395 CopyRegion region; 6396 for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) 6397 { 6398 const VkImageBlit imageBlit = 6399 { 6400 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 6401 { 6402 {0, 0, 0}, 6403 {defaultSize, defaultSize, 1} 6404 }, // VkOffset3D srcOffsets[2]; 6405 6406 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 6407 { 6408 {i, 0, 0}, 6409 {i + defaultFourthSize / j, defaultFourthSize / j, 1} 6410 } // VkOffset3D dstOffset[2]; 6411 }; 6412 region.imageBlit = imageBlit; 6413 params.regions.push_back(region); 6414 } 6415 for (int i = 0; i < defaultSize; i += defaultFourthSize) 6416 { 6417 const VkImageBlit imageBlit = 6418 { 6419 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 6420 { 6421 {i, i, 0}, 6422 {i + defaultFourthSize, i + defaultFourthSize, 1} 6423 }, // VkOffset3D srcOffsets[2]; 6424 6425 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; 6426 { 6427 {i, defaultSize / 2, 0}, 6428 {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1} 6429 } // VkOffset3D dstOffset[2]; 6430 }; 6431 region.imageBlit = imageBlit; 6432 params.regions.push_back(region); 6433 } 6434 6435 if (allocationKind == ALLOCATION_KIND_DEDICATED) 6436 { 6437 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest); 6438 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) 6439 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]); 6440 } 6441 6442 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) 6443 { 6444 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats; 6445 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest; 6446 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) 6447 { 6448 params.src.image.format = compatibleFormats[srcFormatIndex]; 6449 if (!isSupportedByFramework(params.src.image.format)) 6450 continue; 6451 6452 BlitColorTestParams testParams; 6453 testParams.params = params; 6454 testParams.compatibleFormats = compatibleFormats; 6455 testParams.onlyNearest = onlyNearest; 6456 6457 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format); 6458 addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams); 6459 } 6460 } 6461 } 6462 6463 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params) 6464 { 6465 const VkImageLayout blitSrcLayouts[] = 6466 { 6467 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 6468 VK_IMAGE_LAYOUT_GENERAL 6469 }; 6470 const VkImageLayout blitDstLayouts[] = 6471 { 6472 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 6473 VK_IMAGE_LAYOUT_GENERAL 6474 }; 6475 6476 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx) 6477 { 6478 params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx]; 6479 6480 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx) 6481 { 6482 params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx]; 6483 params.filter = VK_FILTER_NEAREST; 6484 6485 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" + 6486 getImageLayoutCaseName(params.dst.image.operationLayout); 6487 const std::string description = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) + 6488 " to " + getImageLayoutCaseName(params.dst.image.operationLayout); 6489 6490 group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params)); 6491 } 6492 } 6493 } 6494 6495 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6496 { 6497 const VkFormat depthAndStencilFormats[] = 6498 { 6499 VK_FORMAT_D16_UNORM, 6500 VK_FORMAT_X8_D24_UNORM_PACK32, 6501 VK_FORMAT_D32_SFLOAT, 6502 VK_FORMAT_S8_UINT, 6503 VK_FORMAT_D16_UNORM_S8_UINT, 6504 VK_FORMAT_D24_UNORM_S8_UINT, 6505 VK_FORMAT_D32_SFLOAT_S8_UINT, 6506 }; 6507 6508 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u }; 6509 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u }; 6510 6511 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex) 6512 { 6513 TestParams params; 6514 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6515 params.src.image.extent = defaultExtent; 6516 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex]; 6517 params.dst.image.extent = defaultExtent; 6518 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6519 params.dst.image.format = params.src.image.format; 6520 params.allocationKind = allocationKind; 6521 6522 CopyRegion region; 6523 for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) 6524 { 6525 const VkOffset3D srcOffset0 = {0, 0, 0}; 6526 const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1}; 6527 const VkOffset3D dstOffset0 = {i, 0, 0}; 6528 const VkOffset3D dstOffset1 = {i + defaultFourthSize / j, defaultFourthSize / j, 1}; 6529 6530 if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) 6531 { 6532 const VkImageBlit imageBlit = 6533 { 6534 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; 6535 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2]; 6536 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; 6537 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2]; 6538 }; 6539 region.imageBlit = imageBlit; 6540 params.regions.push_back(region); 6541 } 6542 if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) 6543 { 6544 const VkImageBlit imageBlit = 6545 { 6546 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; 6547 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2]; 6548 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; 6549 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2]; 6550 }; 6551 region.imageBlit = imageBlit; 6552 params.regions.push_back(region); 6553 } 6554 } 6555 for (int i = 0; i < defaultSize; i += defaultFourthSize) 6556 { 6557 const VkOffset3D srcOffset0 = {i, i, 0}; 6558 const VkOffset3D srcOffset1 = {i + defaultFourthSize, i + defaultFourthSize, 1}; 6559 const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0}; 6560 const VkOffset3D dstOffset1 = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}; 6561 6562 if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) 6563 { 6564 const VkImageBlit imageBlit = 6565 { 6566 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; 6567 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2]; 6568 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; 6569 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2]; 6570 }; 6571 region.imageBlit = imageBlit; 6572 params.regions.push_back(region); 6573 } 6574 if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) 6575 { 6576 const VkImageBlit imageBlit = 6577 { 6578 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; 6579 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2]; 6580 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; 6581 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2]; 6582 }; 6583 region.imageBlit = imageBlit; 6584 params.regions.push_back(region); 6585 } 6586 } 6587 6588 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + 6589 getFormatCaseName(params.dst.image.format); 6590 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) + 6591 " to " + getFormatCaseName(params.dst.image.format); 6592 addTestGroup(group, testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params); 6593 } 6594 } 6595 6596 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams) 6597 { 6598 tcu::TestContext& testCtx = group->getTestContext(); 6599 6600 const VkImageLayout blitSrcLayouts[] = 6601 { 6602 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 6603 VK_IMAGE_LAYOUT_GENERAL 6604 }; 6605 const VkImageLayout blitDstLayouts[] = 6606 { 6607 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 6608 VK_IMAGE_LAYOUT_GENERAL 6609 }; 6610 6611 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx) 6612 { 6613 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx]; 6614 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx) 6615 { 6616 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx]; 6617 6618 testParams.params.filter = VK_FILTER_NEAREST; 6619 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + 6620 getImageLayoutCaseName(testParams.params.dst.image.operationLayout); 6621 const std::string description = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + 6622 " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout); 6623 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params)); 6624 6625 if (!testParams.onlyNearest) 6626 { 6627 testParams.params.filter = VK_FILTER_LINEAR; 6628 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params)); 6629 } 6630 } 6631 } 6632 } 6633 6634 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6635 { 6636 const struct 6637 { 6638 const VkFormat* const compatibleFormats; 6639 const bool onlyNearest; 6640 } colorImageFormatsToTestBlit[] = 6641 { 6642 { compatibleFormatsUInts, true }, 6643 { compatibleFormatsSInts, true }, 6644 { compatibleFormatsFloats, false }, 6645 { compatibleFormatsSrgb, false }, 6646 }; 6647 6648 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit); 6649 6650 TestParams params; 6651 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6652 params.src.image.extent = defaultExtent; 6653 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6654 params.dst.image.extent = defaultExtent; 6655 params.allocationKind = allocationKind; 6656 params.mipLevels = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u; 6657 params.singleCommand = DE_TRUE; 6658 6659 CopyRegion region; 6660 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++) 6661 { 6662 VkImageSubresourceLayers destLayer = defaultSourceLayer; 6663 destLayer.mipLevel = mipLevelNdx; 6664 6665 const VkImageBlit imageBlit = 6666 { 6667 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; 6668 { 6669 {0, 0, 0}, 6670 {defaultSize, defaultSize, 1} 6671 }, // VkOffset3D srcOffsets[2]; 6672 6673 destLayer, // VkImageSubresourceLayers dstSubresource; 6674 { 6675 {0, 0, 0}, 6676 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1} 6677 } // VkOffset3D dstOffset[2]; 6678 }; 6679 region.imageBlit = imageBlit; 6680 params.regions.push_back(region); 6681 } 6682 6683 if (allocationKind == ALLOCATION_KIND_DEDICATED) 6684 { 6685 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest); 6686 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) 6687 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]); 6688 } 6689 6690 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) 6691 { 6692 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats; 6693 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest; 6694 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) 6695 { 6696 params.src.image.format = compatibleFormats[srcFormatIndex]; 6697 params.dst.image.format = compatibleFormats[srcFormatIndex]; 6698 6699 if (!isSupportedByFramework(params.src.image.format)) 6700 continue; 6701 6702 BlitColorTestParams testParams; 6703 testParams.params = params; 6704 testParams.compatibleFormats = compatibleFormats; 6705 testParams.onlyNearest = onlyNearest; 6706 6707 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format); 6708 addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams); 6709 } 6710 } 6711 } 6712 6713 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6714 { 6715 const struct 6716 { 6717 const VkFormat* const compatibleFormats; 6718 const bool onlyNearest; 6719 } colorImageFormatsToTestBlit[] = 6720 { 6721 { compatibleFormatsUInts, true }, 6722 { compatibleFormatsSInts, true }, 6723 { compatibleFormatsFloats, false }, 6724 { compatibleFormatsSrgb, false }, 6725 }; 6726 6727 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit); 6728 6729 TestParams params; 6730 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6731 params.src.image.extent = defaultExtent; 6732 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6733 params.dst.image.extent = defaultExtent; 6734 params.allocationKind = allocationKind; 6735 params.mipLevels = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u; 6736 params.singleCommand = DE_FALSE; 6737 6738 CopyRegion region; 6739 for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++) 6740 { 6741 VkImageSubresourceLayers srcLayer = defaultSourceLayer; 6742 VkImageSubresourceLayers destLayer = defaultSourceLayer; 6743 6744 srcLayer.mipLevel = mipLevelNdx - 1u; 6745 destLayer.mipLevel = mipLevelNdx; 6746 6747 const VkImageBlit imageBlit = 6748 { 6749 srcLayer, // VkImageSubresourceLayers srcSubresource; 6750 { 6751 {0, 0, 0}, 6752 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1} 6753 }, // VkOffset3D srcOffsets[2]; 6754 6755 destLayer, // VkImageSubresourceLayers dstSubresource; 6756 { 6757 {0, 0, 0}, 6758 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1} 6759 } // VkOffset3D dstOffset[2]; 6760 }; 6761 region.imageBlit = imageBlit; 6762 params.regions.push_back(region); 6763 } 6764 6765 if (allocationKind == ALLOCATION_KIND_DEDICATED) 6766 { 6767 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest); 6768 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) 6769 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]); 6770 } 6771 6772 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) 6773 { 6774 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats; 6775 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest; 6776 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) 6777 { 6778 params.src.image.format = compatibleFormats[srcFormatIndex]; 6779 params.dst.image.format = compatibleFormats[srcFormatIndex]; 6780 6781 if (!isSupportedByFramework(params.src.image.format)) 6782 continue; 6783 6784 BlitColorTestParams testParams; 6785 testParams.params = params; 6786 testParams.compatibleFormats = compatibleFormats; 6787 testParams.onlyNearest = onlyNearest; 6788 6789 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format); 6790 addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams); 6791 } 6792 } 6793 } 6794 6795 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6796 { 6797 addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind); 6798 addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind); 6799 } 6800 6801 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6802 { 6803 addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind); 6804 addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind); 6805 addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind); 6806 } 6807 6808 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6809 { 6810 addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind); 6811 addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind); 6812 } 6813 6814 const VkSampleCountFlagBits samples[] = 6815 { 6816 VK_SAMPLE_COUNT_2_BIT, 6817 VK_SAMPLE_COUNT_4_BIT, 6818 VK_SAMPLE_COUNT_8_BIT, 6819 VK_SAMPLE_COUNT_16_BIT, 6820 VK_SAMPLE_COUNT_32_BIT, 6821 VK_SAMPLE_COUNT_64_BIT 6822 }; 6823 const VkExtent3D resolveExtent = {256u, 256u, 1}; 6824 6825 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6826 { 6827 TestParams params; 6828 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6829 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6830 params.src.image.extent = resolveExtent; 6831 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 6832 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6833 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6834 params.dst.image.extent = resolveExtent; 6835 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 6836 params.allocationKind = allocationKind; 6837 6838 { 6839 const VkImageSubresourceLayers sourceLayer = 6840 { 6841 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 6842 0u, // uint32_t mipLevel; 6843 0u, // uint32_t baseArrayLayer; 6844 1u // uint32_t layerCount; 6845 }; 6846 const VkImageResolve testResolve = 6847 { 6848 sourceLayer, // VkImageSubresourceLayers srcSubresource; 6849 {0, 0, 0}, // VkOffset3D srcOffset; 6850 sourceLayer, // VkImageSubresourceLayers dstSubresource; 6851 {0, 0, 0}, // VkOffset3D dstOffset; 6852 resolveExtent, // VkExtent3D extent; 6853 }; 6854 6855 CopyRegion imageResolve; 6856 imageResolve.imageResolve = testResolve; 6857 params.regions.push_back(imageResolve); 6858 } 6859 6860 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 6861 { 6862 params.samples = samples[samplesIndex]; 6863 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); 6864 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params)); 6865 } 6866 } 6867 6868 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6869 { 6870 TestParams params; 6871 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6872 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6873 params.src.image.extent = resolveExtent; 6874 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 6875 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6876 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6877 params.dst.image.extent = resolveExtent; 6878 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 6879 params.allocationKind = allocationKind; 6880 6881 { 6882 const VkImageSubresourceLayers sourceLayer = 6883 { 6884 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 6885 0u, // uint32_t mipLevel; 6886 0u, // uint32_t baseArrayLayer; 6887 1u // uint32_t layerCount; 6888 }; 6889 const VkImageResolve testResolve = 6890 { 6891 sourceLayer, // VkImageSubresourceLayers srcSubresource; 6892 {0, 0, 0}, // VkOffset3D srcOffset; 6893 sourceLayer, // VkImageSubresourceLayers dstSubresource; 6894 {64u, 64u, 0}, // VkOffset3D dstOffset; 6895 {128u, 128u, 1u}, // VkExtent3D extent; 6896 }; 6897 6898 CopyRegion imageResolve; 6899 imageResolve.imageResolve = testResolve; 6900 params.regions.push_back(imageResolve); 6901 } 6902 6903 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 6904 { 6905 params.samples = samples[samplesIndex]; 6906 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); 6907 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params)); 6908 } 6909 } 6910 6911 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6912 { 6913 TestParams params; 6914 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6915 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6916 params.src.image.extent = resolveExtent; 6917 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 6918 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6919 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6920 params.dst.image.extent = resolveExtent; 6921 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 6922 params.allocationKind = allocationKind; 6923 6924 { 6925 const VkImageSubresourceLayers sourceLayer = 6926 { 6927 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 6928 0u, // uint32_t mipLevel; 6929 0u, // uint32_t baseArrayLayer; 6930 1u // uint32_t layerCount; 6931 }; 6932 6933 for (int i = 0; i < 256; i += 64) 6934 { 6935 const VkImageResolve testResolve = 6936 { 6937 sourceLayer, // VkImageSubresourceLayers srcSubresource; 6938 {i, i, 0}, // VkOffset3D srcOffset; 6939 sourceLayer, // VkImageSubresourceLayers dstSubresource; 6940 {i, 0, 0}, // VkOffset3D dstOffset; 6941 {64u, 64u, 1u}, // VkExtent3D extent; 6942 }; 6943 6944 CopyRegion imageResolve; 6945 imageResolve.imageResolve = testResolve; 6946 params.regions.push_back(imageResolve); 6947 } 6948 } 6949 6950 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 6951 { 6952 params.samples = samples[samplesIndex]; 6953 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); 6954 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params)); 6955 } 6956 } 6957 6958 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 6959 { 6960 TestParams params; 6961 params.src.image.imageType = VK_IMAGE_TYPE_2D; 6962 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6963 params.src.image.extent = defaultExtent; 6964 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 6965 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 6966 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 6967 params.dst.image.extent = defaultExtent; 6968 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 6969 params.allocationKind = allocationKind; 6970 6971 { 6972 const VkImageSubresourceLayers sourceLayer = 6973 { 6974 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 6975 0u, // uint32_t mipLevel; 6976 0u, // uint32_t baseArrayLayer; 6977 1u // uint32_t layerCount; 6978 }; 6979 6980 const VkImageResolve testResolve = 6981 { 6982 sourceLayer, // VkImageSubresourceLayers srcSubresource; 6983 {0, 0, 0}, // VkOffset3D srcOffset; 6984 sourceLayer, // VkImageSubresourceLayers dstSubresource; 6985 {0, 0, 0}, // VkOffset3D dstOffset; 6986 defaultExtent, // VkExtent3D extent; 6987 }; 6988 6989 CopyRegion imageResolve; 6990 imageResolve.imageResolve = testResolve; 6991 params.regions.push_back(imageResolve); 6992 } 6993 6994 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 6995 { 6996 params.samples = samples[samplesIndex]; 6997 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); 6998 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE)); 6999 } 7000 } 7001 7002 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 7003 { 7004 TestParams params; 7005 params.src.image.imageType = VK_IMAGE_TYPE_2D; 7006 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 7007 params.src.image.extent = defaultExtent; 7008 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 7009 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 7010 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 7011 params.dst.image.extent = defaultExtent; 7012 params.dst.image.extent.depth = 5u; 7013 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 7014 params.allocationKind = allocationKind; 7015 7016 for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx) 7017 { 7018 const VkImageSubresourceLayers sourceLayer = 7019 { 7020 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 7021 0u, // uint32_t mipLevel; 7022 layerNdx, // uint32_t baseArrayLayer; 7023 1u // uint32_t layerCount; 7024 }; 7025 7026 const VkImageResolve testResolve = 7027 { 7028 sourceLayer, // VkImageSubresourceLayers srcSubresource; 7029 {0, 0, 0}, // VkOffset3D srcOffset; 7030 sourceLayer, // VkImageSubresourceLayers dstSubresource; 7031 {0, 0, 0}, // VkOffset3D dstOffset; 7032 defaultExtent, // VkExtent3D extent; 7033 }; 7034 7035 CopyRegion imageResolve; 7036 imageResolve.imageResolve = testResolve; 7037 params.regions.push_back(imageResolve); 7038 } 7039 7040 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 7041 { 7042 params.samples = samples[samplesIndex]; 7043 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); 7044 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)); 7045 } 7046 } 7047 7048 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 7049 { 7050 tcu::TestContext& testCtx = group->getTestContext(); 7051 TestParams params; 7052 params.src.image.imageType = VK_IMAGE_TYPE_2D; 7053 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; 7054 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 7055 params.dst.image.imageType = VK_IMAGE_TYPE_2D; 7056 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; 7057 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; 7058 params.allocationKind = allocationKind; 7059 7060 { 7061 const VkImageSubresourceLayers sourceLayer = 7062 { 7063 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 7064 0u, // uint32_t mipLevel; 7065 0u, // uint32_t baseArrayLayer; 7066 1u // uint32_t layerCount; 7067 }; 7068 const VkImageResolve testResolve = 7069 { 7070 sourceLayer, // VkImageSubresourceLayers srcSubresource; 7071 {0, 0, 0}, // VkOffset3D srcOffset; 7072 sourceLayer, // VkImageSubresourceLayers dstSubresource; 7073 {0, 0, 0}, // VkOffset3D dstOffset; 7074 resolveExtent, // VkExtent3D extent; 7075 }; 7076 CopyRegion imageResolve; 7077 imageResolve.imageResolve = testResolve; 7078 params.regions.push_back(imageResolve); 7079 } 7080 7081 const VkExtent3D imageExtents[] = 7082 { 7083 { resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth }, 7084 { resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth }, 7085 { resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10 } 7086 }; 7087 7088 for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex) 7089 { 7090 const VkExtent3D& srcImageSize = imageExtents[srcImageExtentIndex]; 7091 params.src.image.extent = srcImageSize; 7092 params.dst.image.extent = resolveExtent; 7093 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 7094 { 7095 params.samples = samples[samplesIndex]; 7096 std::ostringstream testName; 7097 testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]); 7098 std::ostringstream description; 7099 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size (" 7100 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")"; 7101 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params)); 7102 } 7103 } 7104 for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex) 7105 { 7106 const VkExtent3D& dstImageSize = imageExtents[dstImageExtentIndex]; 7107 params.src.image.extent = resolveExtent; 7108 params.dst.image.extent = dstImageSize; 7109 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) 7110 { 7111 params.samples = samples[samplesIndex]; 7112 std::ostringstream testName; 7113 testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]); 7114 std::ostringstream description; 7115 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size (" 7116 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")"; 7117 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params)); 7118 } 7119 } 7120 } 7121 7122 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 7123 { 7124 addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind); 7125 addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind); 7126 addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind); 7127 addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind); 7128 addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind); 7129 addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind); 7130 } 7131 7132 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) 7133 { 7134 addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind); 7135 addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind); 7136 addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind); 7137 addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind); 7138 addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind); 7139 addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind); 7140 } 7141 7142 void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group) 7143 { 7144 addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED); 7145 } 7146 7147 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group) 7148 { 7149 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED); 7150 } 7151 7152 } // anonymous 7153 7154 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) 7155 { 7156 de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests")); 7157 7158 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests)); 7159 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation", "Copies And Blitting Tests For Dedicated Memory Allocation", addDedicatedAllocationCopiesAndBlittingTests)); 7160 7161 return copiesAndBlittingTests.release(); 7162 } 7163 7164 } // api 7165 } // vkt 7166