1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Imagination Technologies 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 Utilities for images. 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktPipelineImageUtil.hpp" 26 #include "vkImageUtil.hpp" 27 #include "vkMemUtil.hpp" 28 #include "vkQueryUtil.hpp" 29 #include "vkRefUtil.hpp" 30 #include "vkCmdUtil.hpp" 31 #include "tcuTextureUtil.hpp" 32 #include "tcuAstcUtil.hpp" 33 #include "deRandom.hpp" 34 #include "deSharedPtr.hpp" 35 36 namespace vkt 37 { 38 namespace pipeline 39 { 40 41 using namespace vk; 42 43 /*! Gets the next multiple of a given divisor */ 44 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value) 45 { 46 if (value % divisor == 0) 47 { 48 return value; 49 } 50 return value + divisor - (value % divisor); 51 } 52 53 /*! Gets the next value that is multiple of all given divisors */ 54 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value) 55 { 56 deUint32 nextMultiple = value; 57 bool nextMultipleFound = false; 58 59 while (true) 60 { 61 nextMultipleFound = true; 62 63 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++) 64 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0); 65 66 if (nextMultipleFound) 67 break; 68 69 DE_ASSERT(nextMultiple < ~((deUint32)0u)); 70 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1); 71 } 72 73 return nextMultiple; 74 } 75 76 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 77 { 78 if (isCompressedFormat(format)) 79 { 80 VkPhysicalDeviceFeatures physicalFeatures; 81 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format); 82 83 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures); 84 85 if (tcu::isAstcFormat(compressedFormat)) 86 { 87 if (!physicalFeatures.textureCompressionASTC_LDR) 88 return false; 89 } 90 else if (tcu::isEtcFormat(compressedFormat)) 91 { 92 if (!physicalFeatures.textureCompressionETC2) 93 return false; 94 } 95 else 96 { 97 DE_FATAL("Unsupported compressed format"); 98 } 99 } 100 101 VkFormatProperties formatProps; 102 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 103 104 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u; 105 } 106 107 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling) 108 { 109 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 110 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR 111 ? formatProperties.linearTilingFeatures 112 : formatProperties.optimalTilingFeatures; 113 114 return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0; 115 } 116 117 bool isMinMaxFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling) 118 { 119 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 120 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR 121 ? formatProperties.linearTilingFeatures 122 : formatProperties.optimalTilingFeatures; 123 124 return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT) != 0; 125 } 126 127 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format) 128 { 129 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format))) 130 { 131 switch (color) 132 { 133 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_INT_OPAQUE_BLACK; 134 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_INT_OPAQUE_WHITE; 135 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK; 136 default: 137 break; 138 } 139 } 140 else 141 { 142 switch (color) 143 { 144 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; 145 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 146 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; 147 default: 148 break; 149 } 150 } 151 152 DE_ASSERT(false); 153 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; 154 } 155 156 void getLookupScaleBias (vk::VkFormat format, tcu::Vec4& lookupScale, tcu::Vec4& lookupBias) 157 { 158 if (!isCompressedFormat(format)) 159 { 160 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format)); 161 162 // Needed to normalize various formats to 0..1 range for writing into RT 163 lookupScale = fmtInfo.lookupScale; 164 lookupBias = fmtInfo.lookupBias; 165 } 166 else 167 { 168 switch (format) 169 { 170 case VK_FORMAT_EAC_R11_SNORM_BLOCK: 171 lookupScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f); 172 lookupBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f); 173 break; 174 175 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 176 lookupScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f); 177 lookupBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f); 178 break; 179 180 default: 181 // else: All supported compressed formats are fine with no normalization. 182 // ASTC LDR blocks decompress to f16 so querying normalization parameters 183 // based on uncompressed formats would actually lead to massive precision loss 184 // and complete lack of coverage in case of R8G8B8A8_UNORM RT. 185 lookupScale = tcu::Vec4(1.0f); 186 lookupBias = tcu::Vec4(0.0f); 187 break; 188 } 189 } 190 } 191 192 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk, 193 vk::VkDevice device, 194 vk::VkQueue queue, 195 deUint32 queueFamilyIndex, 196 vk::Allocator& allocator, 197 vk::VkImage image, 198 vk::VkFormat format, 199 const tcu::UVec2& renderSize) 200 { 201 Move<VkBuffer> buffer; 202 de::MovePtr<Allocation> bufferAlloc; 203 Move<VkCommandPool> cmdPool; 204 Move<VkCommandBuffer> cmdBuffer; 205 Move<VkFence> fence; 206 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 207 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize(); 208 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y())); 209 210 // Create destination buffer 211 { 212 const VkBufferCreateInfo bufferParams = 213 { 214 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 215 DE_NULL, // const void* pNext; 216 0u, // VkBufferCreateFlags flags; 217 pixelDataSize, // VkDeviceSize size; 218 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 219 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 220 0u, // deUint32 queueFamilyIndexCount; 221 DE_NULL // const deUint32* pQueueFamilyIndices; 222 }; 223 224 buffer = createBuffer(vk, device, &bufferParams); 225 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible); 226 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 227 } 228 229 // Create command pool and buffer 230 cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 231 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 232 233 // Create fence 234 fence = createFence(vk, device); 235 236 beginCommandBuffer(vk, *cmdBuffer); 237 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y())); 238 endCommandBuffer(vk, *cmdBuffer); 239 240 submitCommandsAndWait(vk, device, queue, cmdBuffer.get()); 241 242 // Read buffer data 243 invalidateAlloc(vk, device, *bufferAlloc); 244 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr())); 245 246 return resultLevel; 247 } 248 249 void uploadTestTextureInternal (const DeviceInterface& vk, 250 VkDevice device, 251 VkQueue queue, 252 deUint32 queueFamilyIndex, 253 Allocator& allocator, 254 const TestTexture& srcTexture, 255 const TestTexture* srcStencilTexture, 256 tcu::TextureFormat format, 257 VkImage destImage) 258 { 259 Move<VkBuffer> buffer; 260 de::MovePtr<Allocation> bufferAlloc; 261 Move<VkCommandPool> cmdPool; 262 Move<VkCommandBuffer> cmdBuffer; 263 const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(format); 264 deUint32 stencilOffset = 0u; 265 std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions(); 266 deUint32 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize(); 267 268 // Stencil-only texture should be provided if (and only if) the image has a combined DS format 269 DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL)); 270 271 if (srcStencilTexture != DE_NULL) 272 { 273 stencilOffset = static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4)); 274 bufferSize = stencilOffset + srcStencilTexture->getSize(); 275 } 276 277 // Create source buffer 278 { 279 const VkBufferCreateInfo bufferParams = 280 { 281 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 282 DE_NULL, // const void* pNext; 283 0u, // VkBufferCreateFlags flags; 284 bufferSize, // VkDeviceSize size; 285 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 286 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 287 0u, // deUint32 queueFamilyIndexCount; 288 DE_NULL, // const deUint32* pQueueFamilyIndices; 289 }; 290 291 buffer = createBuffer(vk, device, &bufferParams); 292 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible); 293 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 294 } 295 296 // Write buffer data 297 { 298 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr())); 299 300 if (srcStencilTexture != DE_NULL) 301 { 302 DE_ASSERT(stencilOffset != 0u); 303 304 srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset); 305 306 std::vector<VkBufferImageCopy> stencilCopyRegions = srcStencilTexture->getBufferCopyRegions(); 307 for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++) 308 { 309 VkBufferImageCopy region = stencilCopyRegions[regionIdx]; 310 region.bufferOffset += stencilOffset; 311 312 copyRegions.push_back(region); 313 } 314 } 315 316 flushAlloc(vk, device, *bufferAlloc); 317 } 318 319 copyBufferToImage(vk, device, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, imageAspectFlags, srcTexture.getNumLevels(), srcTexture.getArraySize(), destImage); 320 } 321 322 bool checkSparseImageFormatSupport (const VkPhysicalDevice physicalDevice, 323 const InstanceInterface& instance, 324 const VkImageCreateInfo& imageCreateInfo) 325 { 326 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = 327 getPhysicalDeviceSparseImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.samples, imageCreateInfo.usage, imageCreateInfo.tiling); 328 329 return (sparseImageFormatPropVec.size() != 0); 330 } 331 332 void uploadTestTextureInternalSparse (const DeviceInterface& vk, 333 VkDevice device, 334 const VkPhysicalDevice physicalDevice, 335 const InstanceInterface& instance, 336 const VkImageCreateInfo& imageCreateInfo, 337 VkQueue universalQueue, 338 deUint32 universalQueueFamilyIndex, 339 VkQueue sparseQueue, 340 Allocator& allocator, 341 std::vector<de::SharedPtr<Allocation> >& allocations, 342 const TestTexture& srcTexture, 343 const TestTexture* srcStencilTexture, 344 tcu::TextureFormat format, 345 VkImage destImage) 346 { 347 deUint32 bufferSize = (srcTexture.isCompressed()) ? srcTexture.getCompressedSize(): srcTexture.getSize(); 348 const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(format); 349 deUint32 stencilOffset = 0u; 350 const Unique<VkSemaphore> imageMemoryBindSemaphore(createSemaphore(vk, device)); 351 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, universalQueueFamilyIndex); 352 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 353 Move<VkFence> fence = createFence(vk, device); 354 std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions(); 355 Move<VkBuffer> buffer; 356 de::MovePtr<Allocation> bufferAlloc; 357 358 // Stencil-only texture should be provided if (and only if) the image has a combined DS format 359 DE_ASSERT((tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order)) == (srcStencilTexture != DE_NULL)); 360 361 if (srcStencilTexture != DE_NULL) 362 { 363 stencilOffset = static_cast<deUint32>(deAlign32(static_cast<deInt32>(bufferSize), 4)); 364 bufferSize = stencilOffset + srcStencilTexture->getSize(); 365 } 366 367 allocateAndBindSparseImage (vk, device, physicalDevice, instance, imageCreateInfo, imageMemoryBindSemaphore.get(), sparseQueue, allocator, allocations, format, destImage); 368 369 { 370 // Create source buffer 371 const VkBufferCreateInfo bufferParams = 372 { 373 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 374 DE_NULL, // const void* pNext; 375 0u, // VkBufferCreateFlags flags; 376 bufferSize, // VkDeviceSize size; 377 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 378 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 379 0u, // deUint32 queueFamilyIndexCount; 380 DE_NULL, // const deUint32* pQueueFamilyIndices; 381 }; 382 383 buffer = createBuffer(vk, device, &bufferParams); 384 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible); 385 386 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 387 } 388 389 { 390 // Write buffer data 391 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr())); 392 393 if (srcStencilTexture != DE_NULL) 394 { 395 DE_ASSERT(stencilOffset != 0u); 396 397 srcStencilTexture->write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()) + stencilOffset); 398 399 std::vector<VkBufferImageCopy> stencilCopyRegions = srcStencilTexture->getBufferCopyRegions(); 400 for (size_t regionIdx = 0; regionIdx < stencilCopyRegions.size(); regionIdx++) 401 { 402 VkBufferImageCopy region = stencilCopyRegions[regionIdx]; 403 region.bufferOffset += stencilOffset; 404 405 copyRegions.push_back(region); 406 } 407 } 408 409 flushAlloc(vk, device, *bufferAlloc); 410 } 411 412 copyBufferToImage(vk, device, universalQueue, universalQueueFamilyIndex, *buffer, bufferSize, copyRegions, &(*imageMemoryBindSemaphore), imageAspectFlags, imageCreateInfo.mipLevels, imageCreateInfo.arrayLayers, destImage); 413 } 414 415 void uploadTestTexture (const DeviceInterface& vk, 416 VkDevice device, 417 VkQueue queue, 418 deUint32 queueFamilyIndex, 419 Allocator& allocator, 420 const TestTexture& srcTexture, 421 VkImage destImage) 422 { 423 if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type)) 424 { 425 de::MovePtr<TestTexture> srcDepthTexture; 426 de::MovePtr<TestTexture> srcStencilTexture; 427 428 if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order)) 429 { 430 tcu::TextureFormat format; 431 switch (srcTexture.getTextureFormat().type) 432 { 433 case tcu::TextureFormat::UNSIGNED_INT_16_8_8: 434 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16); 435 break; 436 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV: 437 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV); 438 break; 439 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 440 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT); 441 break; 442 default: 443 DE_FATAL("Unexpected source texture format."); 444 break; 445 } 446 srcDepthTexture = srcTexture.copy(format); 447 } 448 449 if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order)) 450 srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL)); 451 452 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *srcDepthTexture, srcStencilTexture.get(), srcTexture.getTextureFormat(), destImage); 453 } 454 else 455 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, DE_NULL, srcTexture.getTextureFormat(), destImage); 456 } 457 458 void uploadTestTextureSparse (const DeviceInterface& vk, 459 VkDevice device, 460 const VkPhysicalDevice physicalDevice, 461 const InstanceInterface& instance, 462 const VkImageCreateInfo& imageCreateInfo, 463 VkQueue universalQueue, 464 deUint32 universalQueueFamilyIndex, 465 VkQueue sparseQueue, 466 Allocator& allocator, 467 std::vector<de::SharedPtr<Allocation> >& allocations, 468 const TestTexture& srcTexture, 469 VkImage destImage) 470 { 471 if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type)) 472 { 473 de::MovePtr<TestTexture> srcDepthTexture; 474 de::MovePtr<TestTexture> srcStencilTexture; 475 476 if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order)) 477 { 478 tcu::TextureFormat format; 479 switch (srcTexture.getTextureFormat().type) 480 { 481 case tcu::TextureFormat::UNSIGNED_INT_16_8_8: 482 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16); 483 break; 484 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV: 485 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV); 486 break; 487 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV: 488 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT); 489 break; 490 default: 491 DE_FATAL("Unexpected source texture format."); 492 break; 493 } 494 srcDepthTexture = srcTexture.copy(format); 495 } 496 497 if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order)) 498 srcStencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL)); 499 500 uploadTestTextureInternalSparse (vk, 501 device, 502 physicalDevice, 503 instance, 504 imageCreateInfo, 505 universalQueue, 506 universalQueueFamilyIndex, 507 sparseQueue, 508 allocator, 509 allocations, 510 *srcDepthTexture, 511 srcStencilTexture.get(), 512 srcTexture.getTextureFormat(), 513 destImage); 514 } 515 else 516 { 517 uploadTestTextureInternalSparse (vk, 518 device, 519 physicalDevice, 520 instance, 521 imageCreateInfo, 522 universalQueue, 523 universalQueueFamilyIndex, 524 sparseQueue, 525 allocator, 526 allocations, 527 srcTexture, 528 DE_NULL, 529 srcTexture.getTextureFormat(), 530 destImage); 531 } 532 } 533 534 // Utilities for test textures 535 536 template<typename TcuTextureType> 537 void allocateLevels (TcuTextureType& texture) 538 { 539 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++) 540 texture.allocLevel(levelNdx); 541 } 542 543 template<typename TcuTextureType> 544 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture) 545 { 546 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels()); 547 548 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++) 549 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx)); 550 551 return levels; 552 } 553 554 // TestTexture 555 556 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth) 557 { 558 DE_ASSERT(width >= 1); 559 DE_ASSERT(height >= 1); 560 DE_ASSERT(depth >= 1); 561 562 DE_UNREF(format); 563 DE_UNREF(width); 564 DE_UNREF(height); 565 DE_UNREF(depth); 566 } 567 568 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth) 569 { 570 DE_ASSERT(width >= 1); 571 DE_ASSERT(height >= 1); 572 DE_ASSERT(depth >= 1); 573 574 DE_UNREF(format); 575 DE_UNREF(width); 576 DE_UNREF(height); 577 DE_UNREF(depth); 578 } 579 580 TestTexture::~TestTexture (void) 581 { 582 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++) 583 delete m_compressedLevels[levelNdx]; 584 } 585 586 deUint32 TestTexture::getSize (void) const 587 { 588 std::vector<deUint32> offsetMultiples; 589 deUint32 textureSize = 0; 590 591 offsetMultiples.push_back(4); 592 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize()); 593 594 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 595 { 596 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 597 { 598 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx); 599 textureSize = getNextMultiple(offsetMultiples, textureSize); 600 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize(); 601 } 602 } 603 604 return textureSize; 605 } 606 607 deUint32 TestTexture::getCompressedSize (void) const 608 { 609 if (!isCompressed()) 610 throw tcu::InternalError("Texture is not compressed"); 611 612 std::vector<deUint32> offsetMultiples; 613 deUint32 textureSize = 0; 614 615 offsetMultiples.push_back(4); 616 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat())); 617 618 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 619 { 620 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 621 { 622 textureSize = getNextMultiple(offsetMultiples, textureSize); 623 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize(); 624 } 625 } 626 627 return textureSize; 628 } 629 630 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) 631 { 632 DE_ASSERT(level >= 0 && level < getNumLevels()); 633 DE_ASSERT(layer >= 0 && layer < getArraySize()); 634 635 return *m_compressedLevels[level * getArraySize() + layer]; 636 } 637 638 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const 639 { 640 DE_ASSERT(level >= 0 && level < getNumLevels()); 641 DE_ASSERT(layer >= 0 && layer < getArraySize()); 642 643 return *m_compressedLevels[level * getArraySize() + layer]; 644 } 645 646 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const 647 { 648 std::vector<deUint32> offsetMultiples; 649 std::vector<VkBufferImageCopy> regions; 650 deUint32 layerDataOffset = 0; 651 652 offsetMultiples.push_back(4); 653 654 if (isCompressed()) 655 { 656 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat())); 657 658 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 659 { 660 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 661 { 662 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx); 663 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat()); 664 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 665 666 const VkBufferImageCopy layerRegion = 667 { 668 layerDataOffset, // VkDeviceSize bufferOffset; 669 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength; 670 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight; 671 { // VkImageSubresourceLayers imageSubresource; 672 VK_IMAGE_ASPECT_COLOR_BIT, 673 (deUint32)levelNdx, 674 (deUint32)layerNdx, 675 1u 676 }, 677 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 678 { // VkExtent3D imageExtent; 679 (deUint32)level.getWidth(), 680 (deUint32)level.getHeight(), 681 (deUint32)level.getDepth() 682 } 683 }; 684 685 regions.push_back(layerRegion); 686 layerDataOffset += level.getDataSize(); 687 } 688 } 689 } 690 else 691 { 692 std::vector<VkImageAspectFlags> imageAspects; 693 tcu::TextureFormat textureFormat = getTextureFormat(); 694 695 if (tcu::hasDepthComponent(textureFormat.order)) 696 imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT); 697 698 if (tcu::hasStencilComponent(textureFormat.order)) 699 imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT); 700 701 if (imageAspects.empty()) 702 imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT); 703 704 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize()); 705 706 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 707 { 708 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 709 { 710 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx); 711 712 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 713 714 for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex) 715 { 716 const VkBufferImageCopy layerRegion = 717 { 718 layerDataOffset, // VkDeviceSize bufferOffset; 719 (deUint32)level.getWidth(), // deUint32 bufferRowLength; 720 (deUint32)level.getHeight(), // deUint32 bufferImageHeight; 721 { // VkImageSubresourceLayers imageSubresource; 722 imageAspects[aspectIndex], 723 (deUint32)levelNdx, 724 (deUint32)layerNdx, 725 1u 726 }, 727 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 728 { // VkExtent3D imageExtent; 729 (deUint32)level.getWidth(), 730 (deUint32)level.getHeight(), 731 (deUint32)level.getDepth() 732 } 733 }; 734 735 regions.push_back(layerRegion); 736 } 737 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize(); 738 } 739 } 740 } 741 742 return regions; 743 } 744 745 void TestTexture::write (deUint8* destPtr) const 746 { 747 std::vector<deUint32> offsetMultiples; 748 deUint32 levelOffset = 0; 749 750 offsetMultiples.push_back(4); 751 752 if (isCompressed()) 753 { 754 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat())); 755 756 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 757 { 758 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 759 { 760 levelOffset = getNextMultiple(offsetMultiples, levelOffset); 761 762 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx); 763 764 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize()); 765 levelOffset += compressedTex.getDataSize(); 766 } 767 } 768 } 769 else 770 { 771 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize()); 772 773 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 774 { 775 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 776 { 777 levelOffset = getNextMultiple(offsetMultiples, levelOffset); 778 779 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx); 780 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset); 781 782 tcu::copy(destAccess, srcAccess); 783 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize(); 784 } 785 } 786 } 787 } 788 789 void TestTexture::copyToTexture (TestTexture& destTexture) const 790 { 791 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 792 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 793 tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx)); 794 } 795 796 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels) 797 { 798 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++) 799 TestTexture::fillWithGradient(levels[levelNdx]); 800 } 801 802 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels) 803 { 804 // Generate random compressed data and update decompressed data 805 806 de::Random random(123); 807 808 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++) 809 { 810 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx]; 811 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth()); 812 deUint8* const compressedData = (deUint8*)compressedLevel->getData(); 813 814 if (tcu::isAstcFormat(format)) 815 { 816 // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks 817 tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES, 818 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32()); 819 } 820 else 821 { 822 // Generate random compressed data 823 // Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format 824 if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8) 825 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++) 826 compressedData[byteNdx] = 0xFF & random.getUint32(); 827 } 828 829 m_compressedLevels.push_back(compressedLevel); 830 831 // Store decompressed data 832 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR)); 833 } 834 } 835 836 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess) 837 { 838 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat()); 839 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax); 840 } 841 842 // TestTexture1D 843 844 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width) 845 : TestTexture (format, width, 1, 1) 846 , m_texture (format, width) 847 { 848 allocateLevels(m_texture); 849 TestTexture::populateLevels(getLevelsVector(m_texture)); 850 } 851 852 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width) 853 : TestTexture (format, width, 1, 1) 854 , m_texture (tcu::getUncompressedFormat(format), width) 855 { 856 allocateLevels(m_texture); 857 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture)); 858 } 859 860 TestTexture1D::~TestTexture1D (void) 861 { 862 } 863 864 int TestTexture1D::getNumLevels (void) const 865 { 866 return m_texture.getNumLevels(); 867 } 868 869 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer) 870 { 871 DE_ASSERT(layer == 0); 872 DE_UNREF(layer); 873 return m_texture.getLevel(level); 874 } 875 876 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const 877 { 878 DE_ASSERT(layer == 0); 879 DE_UNREF(layer); 880 return m_texture.getLevel(level); 881 } 882 883 const tcu::Texture1D& TestTexture1D::getTexture (void) const 884 { 885 return m_texture; 886 } 887 888 tcu::Texture1D& TestTexture1D::getTexture (void) 889 { 890 return m_texture; 891 } 892 893 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const 894 { 895 DE_ASSERT(!isCompressed()); 896 897 de::MovePtr<TestTexture> texture (new TestTexture1D(format, m_texture.getWidth())); 898 899 copyToTexture(*texture); 900 901 return texture; 902 } 903 904 // TestTexture1DArray 905 906 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize) 907 : TestTexture (format, width, 1, arraySize) 908 , m_texture (format, width, arraySize) 909 { 910 allocateLevels(m_texture); 911 TestTexture::populateLevels(getLevelsVector(m_texture)); 912 } 913 914 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize) 915 : TestTexture (format, width, 1, arraySize) 916 , m_texture (tcu::getUncompressedFormat(format), width, arraySize) 917 { 918 allocateLevels(m_texture); 919 920 std::vector<tcu::PixelBufferAccess> layers; 921 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++) 922 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++) 923 layers.push_back(getLevel(levelNdx, layerNdx)); 924 925 TestTexture::populateCompressedLevels(format, layers); 926 } 927 928 TestTexture1DArray::~TestTexture1DArray (void) 929 { 930 } 931 932 int TestTexture1DArray::getNumLevels (void) const 933 { 934 return m_texture.getNumLevels(); 935 } 936 937 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) 938 { 939 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level); 940 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize(); 941 const deUint32 layerOffset = layerSize * layer; 942 943 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 944 } 945 946 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const 947 { 948 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level); 949 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize(); 950 const deUint32 layerOffset = layerSize * layer; 951 952 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 953 } 954 955 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const 956 { 957 return m_texture; 958 } 959 960 tcu::Texture1DArray& TestTexture1DArray::getTexture (void) 961 { 962 return m_texture; 963 } 964 965 int TestTexture1DArray::getArraySize (void) const 966 { 967 return m_texture.getNumLayers(); 968 } 969 970 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const 971 { 972 DE_ASSERT(!isCompressed()); 973 974 de::MovePtr<TestTexture> texture (new TestTexture1DArray(format, m_texture.getWidth(), getArraySize())); 975 976 copyToTexture(*texture); 977 978 return texture; 979 } 980 981 // TestTexture2D 982 983 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height) 984 : TestTexture (format, width, height, 1) 985 , m_texture (format, width, height) 986 { 987 allocateLevels(m_texture); 988 TestTexture::populateLevels(getLevelsVector(m_texture)); 989 } 990 991 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height, int miplevels) 992 : TestTexture(format, width, height, 1) 993 , m_texture(format, width, height, miplevels) 994 { 995 allocateLevels(m_texture); 996 TestTexture::populateLevels(getLevelsVector(m_texture)); 997 } 998 999 1000 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height) 1001 : TestTexture (format, width, height, 1) 1002 , m_texture (tcu::getUncompressedFormat(format), width, height) 1003 { 1004 allocateLevels(m_texture); 1005 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture)); 1006 } 1007 1008 TestTexture2D::~TestTexture2D (void) 1009 { 1010 } 1011 1012 int TestTexture2D::getNumLevels (void) const 1013 { 1014 return m_texture.getNumLevels(); 1015 } 1016 1017 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer) 1018 { 1019 DE_ASSERT(layer == 0); 1020 DE_UNREF(layer); 1021 return m_texture.getLevel(level); 1022 } 1023 1024 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const 1025 { 1026 DE_ASSERT(layer == 0); 1027 DE_UNREF(layer); 1028 return m_texture.getLevel(level); 1029 } 1030 1031 const tcu::Texture2D& TestTexture2D::getTexture (void) const 1032 { 1033 return m_texture; 1034 } 1035 1036 tcu::Texture2D& TestTexture2D::getTexture (void) 1037 { 1038 return m_texture; 1039 } 1040 1041 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const 1042 { 1043 DE_ASSERT(!isCompressed()); 1044 1045 de::MovePtr<TestTexture> texture (new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight())); 1046 1047 copyToTexture(*texture); 1048 1049 return texture; 1050 } 1051 1052 // TestTexture2DArray 1053 1054 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize) 1055 : TestTexture (format, width, height, arraySize) 1056 , m_texture (format, width, height, arraySize) 1057 { 1058 allocateLevels(m_texture); 1059 TestTexture::populateLevels(getLevelsVector(m_texture)); 1060 } 1061 1062 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize) 1063 : TestTexture (format, width, height, arraySize) 1064 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize) 1065 { 1066 allocateLevels(m_texture); 1067 1068 std::vector<tcu::PixelBufferAccess> layers; 1069 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++) 1070 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++) 1071 layers.push_back(getLevel(levelNdx, layerNdx)); 1072 1073 TestTexture::populateCompressedLevels(format, layers); 1074 } 1075 1076 TestTexture2DArray::~TestTexture2DArray (void) 1077 { 1078 } 1079 1080 int TestTexture2DArray::getNumLevels (void) const 1081 { 1082 return m_texture.getNumLevels(); 1083 } 1084 1085 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) 1086 { 1087 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level); 1088 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1089 const deUint32 layerOffset = layerSize * layer; 1090 1091 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1092 } 1093 1094 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const 1095 { 1096 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level); 1097 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1098 const deUint32 layerOffset = layerSize * layer; 1099 1100 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1101 } 1102 1103 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const 1104 { 1105 return m_texture; 1106 } 1107 1108 tcu::Texture2DArray& TestTexture2DArray::getTexture (void) 1109 { 1110 return m_texture; 1111 } 1112 1113 int TestTexture2DArray::getArraySize (void) const 1114 { 1115 return m_texture.getNumLayers(); 1116 } 1117 1118 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const 1119 { 1120 DE_ASSERT(!isCompressed()); 1121 1122 de::MovePtr<TestTexture> texture (new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize())); 1123 1124 copyToTexture(*texture); 1125 1126 return texture; 1127 } 1128 1129 // TestTexture3D 1130 1131 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth) 1132 : TestTexture (format, width, height, depth) 1133 , m_texture (format, width, height, depth) 1134 { 1135 allocateLevels(m_texture); 1136 TestTexture::populateLevels(getLevelsVector(m_texture)); 1137 } 1138 1139 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth) 1140 : TestTexture (format, width, height, depth) 1141 , m_texture (tcu::getUncompressedFormat(format), width, height, depth) 1142 { 1143 allocateLevels(m_texture); 1144 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture)); 1145 } 1146 1147 TestTexture3D::~TestTexture3D (void) 1148 { 1149 } 1150 1151 int TestTexture3D::getNumLevels (void) const 1152 { 1153 return m_texture.getNumLevels(); 1154 } 1155 1156 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer) 1157 { 1158 DE_ASSERT(layer == 0); 1159 DE_UNREF(layer); 1160 return m_texture.getLevel(level); 1161 } 1162 1163 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const 1164 { 1165 DE_ASSERT(layer == 0); 1166 DE_UNREF(layer); 1167 return m_texture.getLevel(level); 1168 } 1169 1170 const tcu::Texture3D& TestTexture3D::getTexture (void) const 1171 { 1172 return m_texture; 1173 } 1174 1175 tcu::Texture3D& TestTexture3D::getTexture (void) 1176 { 1177 return m_texture; 1178 } 1179 1180 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const 1181 { 1182 DE_ASSERT(!isCompressed()); 1183 1184 de::MovePtr<TestTexture> texture (new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth())); 1185 1186 copyToTexture(*texture); 1187 1188 return texture; 1189 } 1190 1191 // TestTextureCube 1192 1193 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] = 1194 { 1195 tcu::CUBEFACE_POSITIVE_X, 1196 tcu::CUBEFACE_NEGATIVE_X, 1197 tcu::CUBEFACE_POSITIVE_Y, 1198 tcu::CUBEFACE_NEGATIVE_Y, 1199 tcu::CUBEFACE_POSITIVE_Z, 1200 tcu::CUBEFACE_NEGATIVE_Z 1201 }; 1202 1203 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size) 1204 : TestTexture (format, size, size, 1) 1205 , m_texture (format, size) 1206 { 1207 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 1208 { 1209 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 1210 { 1211 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx); 1212 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx])); 1213 } 1214 } 1215 } 1216 1217 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size) 1218 : TestTexture (format, size, size, 1) 1219 , m_texture (tcu::getUncompressedFormat(format), size) 1220 { 1221 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST); 1222 1223 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 1224 { 1225 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 1226 { 1227 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx); 1228 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]); 1229 } 1230 } 1231 1232 TestTexture::populateCompressedLevels(format, levels); 1233 } 1234 1235 TestTextureCube::~TestTextureCube (void) 1236 { 1237 } 1238 1239 int TestTextureCube::getNumLevels (void) const 1240 { 1241 return m_texture.getNumLevels(); 1242 } 1243 1244 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer) 1245 { 1246 return m_texture.getLevelFace(level, tcuFaceMapping[layer]); 1247 } 1248 1249 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const 1250 { 1251 return m_texture.getLevelFace(level, tcuFaceMapping[layer]); 1252 } 1253 1254 int TestTextureCube::getArraySize (void) const 1255 { 1256 return (int)tcu::CUBEFACE_LAST; 1257 } 1258 1259 const tcu::TextureCube& TestTextureCube::getTexture (void) const 1260 { 1261 return m_texture; 1262 } 1263 1264 tcu::TextureCube& TestTextureCube::getTexture (void) 1265 { 1266 return m_texture; 1267 } 1268 1269 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const 1270 { 1271 DE_ASSERT(!isCompressed()); 1272 1273 de::MovePtr<TestTexture> texture (new TestTextureCube(format, m_texture.getSize())); 1274 1275 copyToTexture(*texture); 1276 1277 return texture; 1278 } 1279 1280 // TestTextureCubeArray 1281 1282 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize) 1283 : TestTexture (format, size, size, arraySize) 1284 , m_texture (format, size, arraySize) 1285 { 1286 allocateLevels(m_texture); 1287 TestTexture::populateLevels(getLevelsVector(m_texture)); 1288 } 1289 1290 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize) 1291 : TestTexture (format, size, size, arraySize) 1292 , m_texture (tcu::getUncompressedFormat(format), size, arraySize) 1293 { 1294 DE_ASSERT(arraySize % 6 == 0); 1295 1296 allocateLevels(m_texture); 1297 1298 std::vector<tcu::PixelBufferAccess> layers; 1299 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++) 1300 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++) 1301 layers.push_back(getLevel(levelNdx, layerNdx)); 1302 1303 TestTexture::populateCompressedLevels(format, layers); 1304 } 1305 1306 TestTextureCubeArray::~TestTextureCubeArray (void) 1307 { 1308 } 1309 1310 int TestTextureCubeArray::getNumLevels (void) const 1311 { 1312 return m_texture.getNumLevels(); 1313 } 1314 1315 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) 1316 { 1317 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level); 1318 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1319 const deUint32 layerOffset = layerSize * layer; 1320 1321 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1322 } 1323 1324 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const 1325 { 1326 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level); 1327 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1328 const deUint32 layerOffset = layerSize * layer; 1329 1330 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1331 } 1332 1333 int TestTextureCubeArray::getArraySize (void) const 1334 { 1335 return m_texture.getDepth(); 1336 } 1337 1338 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const 1339 { 1340 return m_texture; 1341 } 1342 1343 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) 1344 { 1345 return m_texture; 1346 } 1347 1348 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const 1349 { 1350 DE_ASSERT(!isCompressed()); 1351 1352 de::MovePtr<TestTexture> texture (new TestTextureCubeArray(format, m_texture.getSize(), getArraySize())); 1353 1354 copyToTexture(*texture); 1355 1356 return texture; 1357 } 1358 1359 } // pipeline 1360 } // vkt 1361