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 "tcuTextureUtil.hpp" 31 #include "tcuAstcUtil.hpp" 32 #include "deRandom.hpp" 33 34 namespace vkt 35 { 36 namespace pipeline 37 { 38 39 using namespace vk; 40 41 /*! Gets the next multiple of a given divisor */ 42 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value) 43 { 44 if (value % divisor == 0) 45 { 46 return value; 47 } 48 return value + divisor - (value % divisor); 49 } 50 51 /*! Gets the next value that is multiple of all given divisors */ 52 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value) 53 { 54 deUint32 nextMultiple = value; 55 bool nextMultipleFound = false; 56 57 while (true) 58 { 59 nextMultipleFound = true; 60 61 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++) 62 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0); 63 64 if (nextMultipleFound) 65 break; 66 67 DE_ASSERT(nextMultiple < ~((deUint32)0u)); 68 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1); 69 } 70 71 return nextMultiple; 72 } 73 74 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 75 { 76 if (isCompressedFormat(format)) 77 { 78 VkPhysicalDeviceFeatures physicalFeatures; 79 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format); 80 81 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures); 82 83 if (tcu::isAstcFormat(compressedFormat)) 84 { 85 if (!physicalFeatures.textureCompressionASTC_LDR) 86 return false; 87 } 88 else if (tcu::isEtcFormat(compressedFormat)) 89 { 90 if (!physicalFeatures.textureCompressionETC2) 91 return false; 92 } 93 else 94 { 95 DE_FATAL("Unsupported compressed format"); 96 } 97 } 98 99 VkFormatProperties formatProps; 100 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 101 102 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u; 103 } 104 105 // \todo [2016-01-21 pyry] Update this to just rely on vkDefs.hpp once 106 // CTS has been updated to 1.0.2. 107 enum 108 { 109 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, 110 }; 111 112 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling) 113 { 114 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 115 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR 116 ? formatProperties.linearTilingFeatures 117 : formatProperties.optimalTilingFeatures; 118 119 switch (format) 120 { 121 case VK_FORMAT_R32_SFLOAT: 122 case VK_FORMAT_R32G32_SFLOAT: 123 case VK_FORMAT_R32G32B32_SFLOAT: 124 case VK_FORMAT_R32G32B32A32_SFLOAT: 125 case VK_FORMAT_R64_SFLOAT: 126 case VK_FORMAT_R64G64_SFLOAT: 127 case VK_FORMAT_R64G64B64_SFLOAT: 128 case VK_FORMAT_R64G64B64A64_SFLOAT: 129 return (formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) != 0; 130 131 default: 132 // \todo [2016-01-21 pyry] Check for all formats once drivers have been updated to 1.0.2 133 // and we have tests to verify format properties. 134 return true; 135 } 136 } 137 138 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format) 139 { 140 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format))) 141 { 142 switch (color) 143 { 144 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_INT_OPAQUE_BLACK; 145 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_INT_OPAQUE_WHITE; 146 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK; 147 default: 148 break; 149 } 150 } 151 else 152 { 153 switch (color) 154 { 155 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; 156 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; 157 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; 158 default: 159 break; 160 } 161 } 162 163 DE_ASSERT(false); 164 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; 165 } 166 167 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk, 168 vk::VkDevice device, 169 vk::VkQueue queue, 170 deUint32 queueFamilyIndex, 171 vk::Allocator& allocator, 172 vk::VkImage image, 173 vk::VkFormat format, 174 const tcu::UVec2& renderSize) 175 { 176 Move<VkBuffer> buffer; 177 de::MovePtr<Allocation> bufferAlloc; 178 Move<VkCommandPool> cmdPool; 179 Move<VkCommandBuffer> cmdBuffer; 180 Move<VkFence> fence; 181 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 182 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize(); 183 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y())); 184 185 // Create destination buffer 186 { 187 const VkBufferCreateInfo bufferParams = 188 { 189 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 190 DE_NULL, // const void* pNext; 191 0u, // VkBufferCreateFlags flags; 192 pixelDataSize, // VkDeviceSize size; 193 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 194 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 195 0u, // deUint32 queueFamilyIndexCount; 196 DE_NULL // const deUint32* pQueueFamilyIndices; 197 }; 198 199 buffer = createBuffer(vk, device, &bufferParams); 200 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible); 201 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 202 } 203 204 // Create command pool and buffer 205 { 206 const VkCommandPoolCreateInfo cmdPoolParams = 207 { 208 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 209 DE_NULL, // const void* pNext; 210 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; 211 queueFamilyIndex, // deUint32 queueFamilyIndex; 212 }; 213 214 cmdPool = createCommandPool(vk, device, &cmdPoolParams); 215 216 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 217 { 218 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 219 DE_NULL, // const void* pNext; 220 *cmdPool, // VkCommandPool commandPool; 221 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 222 1u // deUint32 bufferCount; 223 }; 224 225 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo); 226 } 227 228 // Create fence 229 { 230 const VkFenceCreateInfo fenceParams = 231 { 232 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 233 DE_NULL, // const void* pNext; 234 0u // VkFenceCreateFlags flags; 235 }; 236 237 fence = createFence(vk, device, &fenceParams); 238 } 239 240 // Barriers for copying image to buffer 241 242 const VkImageMemoryBarrier imageBarrier = 243 { 244 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 245 DE_NULL, // const void* pNext; 246 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; 247 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 248 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 249 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 250 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 251 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 252 image, // VkImage image; 253 { // VkImageSubresourceRange subresourceRange; 254 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 255 0u, // deUint32 baseMipLevel; 256 1u, // deUint32 mipLevels; 257 0u, // deUint32 baseArraySlice; 258 1u // deUint32 arraySize; 259 } 260 }; 261 262 const VkBufferMemoryBarrier bufferBarrier = 263 { 264 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 265 DE_NULL, // const void* pNext; 266 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 267 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask; 268 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 269 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 270 *buffer, // VkBuffer buffer; 271 0u, // VkDeviceSize offset; 272 pixelDataSize // VkDeviceSize size; 273 }; 274 275 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 276 { 277 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 278 DE_NULL, // const void* pNext; 279 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 280 (const VkCommandBufferInheritanceInfo*)DE_NULL, 281 }; 282 283 // Copy image to buffer 284 285 const VkBufferImageCopy copyRegion = 286 { 287 0u, // VkDeviceSize bufferOffset; 288 (deUint32)renderSize.x(), // deUint32 bufferRowLength; 289 (deUint32)renderSize.y(), // deUint32 bufferImageHeight; 290 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource; 291 { 0, 0, 0 }, // VkOffset3D imageOffset; 292 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent; 293 }; 294 295 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 296 vk.cmdPipelineBarrier(*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, 1, &imageBarrier); 297 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region); 298 vk.cmdPipelineBarrier(*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); 299 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 300 301 const VkSubmitInfo submitInfo = 302 { 303 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 304 DE_NULL, // const void* pNext; 305 0u, // deUint32 waitSemaphoreCount; 306 DE_NULL, // const VkSemaphore* pWaitSemaphores; 307 DE_NULL, 308 1u, // deUint32 commandBufferCount; 309 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 310 0u, // deUint32 signalSemaphoreCount; 311 DE_NULL // const VkSemaphore* pSignalSemaphores; 312 }; 313 314 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 315 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */)); 316 317 // Read buffer data 318 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); 319 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr())); 320 321 return resultLevel; 322 } 323 324 void uploadTestTexture (const DeviceInterface& vk, 325 VkDevice device, 326 VkQueue queue, 327 deUint32 queueFamilyIndex, 328 Allocator& allocator, 329 const TestTexture& srcTexture, 330 VkImage destImage) 331 { 332 deUint32 bufferSize; 333 Move<VkBuffer> buffer; 334 de::MovePtr<Allocation> bufferAlloc; 335 Move<VkCommandPool> cmdPool; 336 Move<VkCommandBuffer> cmdBuffer; 337 Move<VkFence> fence; 338 std::vector<deUint32> levelDataSizes; 339 340 // Calculate buffer size 341 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize(); 342 343 // Create source buffer 344 { 345 const VkBufferCreateInfo bufferParams = 346 { 347 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 348 DE_NULL, // const void* pNext; 349 0u, // VkBufferCreateFlags flags; 350 bufferSize, // VkDeviceSize size; 351 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage; 352 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 353 0u, // deUint32 queueFamilyIndexCount; 354 DE_NULL, // const deUint32* pQueueFamilyIndices; 355 }; 356 357 buffer = createBuffer(vk, device, &bufferParams); 358 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible); 359 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 360 } 361 362 // Create command pool and buffer 363 { 364 const VkCommandPoolCreateInfo cmdPoolParams = 365 { 366 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 367 DE_NULL, // const void* pNext; 368 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; 369 queueFamilyIndex, // deUint32 queueFamilyIndex; 370 }; 371 372 cmdPool = createCommandPool(vk, device, &cmdPoolParams); 373 374 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = 375 { 376 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 377 DE_NULL, // const void* pNext; 378 *cmdPool, // VkCommandPool commandPool; 379 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 380 1u, // deUint32 bufferCount; 381 }; 382 383 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo); 384 } 385 386 // Create fence 387 { 388 const VkFenceCreateInfo fenceParams = 389 { 390 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 391 DE_NULL, // const void* pNext; 392 0u // VkFenceCreateFlags flags; 393 }; 394 395 fence = createFence(vk, device, &fenceParams); 396 } 397 398 // Barriers for copying buffer to image 399 const VkBufferMemoryBarrier preBufferBarrier = 400 { 401 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 402 DE_NULL, // const void* pNext; 403 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask; 404 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; 405 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 406 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 407 *buffer, // VkBuffer buffer; 408 0u, // VkDeviceSize offset; 409 bufferSize // VkDeviceSize size; 410 }; 411 412 const VkImageMemoryBarrier preImageBarrier = 413 { 414 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 415 DE_NULL, // const void* pNext; 416 0u, // VkAccessFlags srcAccessMask; 417 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; 418 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 419 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; 420 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 421 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 422 destImage, // VkImage image; 423 { // VkImageSubresourceRange subresourceRange; 424 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 425 0u, // deUint32 baseMipLevel; 426 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels; 427 0u, // deUint32 baseArraySlice; 428 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize; 429 } 430 }; 431 432 const VkImageMemoryBarrier postImageBarrier = 433 { 434 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 435 DE_NULL, // const void* pNext; 436 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; 437 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask; 438 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; 439 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout; 440 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 441 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; 442 destImage, // VkImage image; 443 { // VkImageSubresourceRange subresourceRange; 444 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 445 0u, // deUint32 baseMipLevel; 446 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels; 447 0u, // deUint32 baseArraySlice; 448 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize; 449 } 450 }; 451 452 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 453 { 454 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 455 DE_NULL, // const void* pNext; 456 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 457 (const VkCommandBufferInheritanceInfo*)DE_NULL, 458 }; 459 460 const std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions(); 461 462 // Write buffer data 463 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr())); 464 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize); 465 466 // Copy buffer to image 467 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); 468 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier); 469 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data()); 470 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); 471 472 VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); 473 474 const VkSubmitInfo submitInfo = 475 { 476 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 477 DE_NULL, // const void* pNext; 478 0u, // deUint32 waitSemaphoreCount; 479 DE_NULL, // const VkSemaphore* pWaitSemaphores; 480 DE_NULL, 481 1u, // deUint32 commandBufferCount; 482 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 483 0u, // deUint32 signalSemaphoreCount; 484 DE_NULL // const VkSemaphore* pSignalSemaphores; 485 }; 486 487 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); 488 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */)); 489 } 490 491 492 // Utilities for test textures 493 494 template<typename TcuTextureType> 495 void allocateLevels (TcuTextureType& texture) 496 { 497 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++) 498 texture.allocLevel(levelNdx); 499 } 500 501 template<typename TcuTextureType> 502 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture) 503 { 504 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels()); 505 506 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++) 507 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx)); 508 509 return levels; 510 } 511 512 513 // TestTexture 514 515 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth) 516 { 517 DE_ASSERT(width >= 1); 518 DE_ASSERT(height >= 1); 519 DE_ASSERT(depth >= 1); 520 521 DE_UNREF(format); 522 DE_UNREF(width); 523 DE_UNREF(height); 524 DE_UNREF(depth); 525 } 526 527 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth) 528 { 529 DE_ASSERT(width >= 1); 530 DE_ASSERT(height >= 1); 531 DE_ASSERT(depth >= 1); 532 533 DE_UNREF(format); 534 DE_UNREF(width); 535 DE_UNREF(height); 536 DE_UNREF(depth); 537 } 538 539 TestTexture::~TestTexture (void) 540 { 541 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++) 542 delete m_compressedLevels[levelNdx]; 543 } 544 545 deUint32 TestTexture::getSize (void) const 546 { 547 std::vector<deUint32> offsetMultiples; 548 deUint32 textureSize = 0; 549 550 offsetMultiples.push_back(4); 551 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize()); 552 553 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 554 { 555 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 556 { 557 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx); 558 textureSize = getNextMultiple(offsetMultiples, textureSize); 559 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize(); 560 } 561 } 562 563 return textureSize; 564 } 565 566 deUint32 TestTexture::getCompressedSize (void) const 567 { 568 if (!isCompressed()) 569 throw tcu::InternalError("Texture is not compressed"); 570 571 std::vector<deUint32> offsetMultiples; 572 deUint32 textureSize = 0; 573 574 offsetMultiples.push_back(4); 575 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat())); 576 577 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 578 { 579 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 580 { 581 textureSize = getNextMultiple(offsetMultiples, textureSize); 582 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize(); 583 } 584 } 585 586 return textureSize; 587 } 588 589 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) 590 { 591 DE_ASSERT(level >= 0 && level < getNumLevels()); 592 DE_ASSERT(layer >= 0 && layer < getArraySize()); 593 594 return *m_compressedLevels[level * getArraySize() + layer]; 595 } 596 597 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const 598 { 599 DE_ASSERT(level >= 0 && level < getNumLevels()); 600 DE_ASSERT(layer >= 0 && layer < getArraySize()); 601 602 return *m_compressedLevels[level * getArraySize() + layer]; 603 } 604 605 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const 606 { 607 std::vector<deUint32> offsetMultiples; 608 std::vector<VkBufferImageCopy> regions; 609 deUint32 layerDataOffset = 0; 610 611 offsetMultiples.push_back(4); 612 613 if (isCompressed()) 614 { 615 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat())); 616 617 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 618 { 619 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 620 { 621 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx); 622 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat()); 623 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 624 625 const VkBufferImageCopy layerRegion = 626 { 627 layerDataOffset, // VkDeviceSize bufferOffset; 628 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength; 629 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight; 630 { // VkImageSubresourceLayers imageSubresource; 631 VK_IMAGE_ASPECT_COLOR_BIT, 632 (deUint32)levelNdx, 633 (deUint32)layerNdx, 634 1u 635 }, 636 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 637 { // VkExtent3D imageExtent; 638 (deUint32)level.getWidth(), 639 (deUint32)level.getHeight(), 640 (deUint32)level.getDepth() 641 } 642 }; 643 644 regions.push_back(layerRegion); 645 layerDataOffset += level.getDataSize(); 646 } 647 } 648 } 649 else 650 { 651 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize()); 652 653 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 654 { 655 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 656 { 657 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx); 658 659 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset); 660 661 const VkBufferImageCopy layerRegion = 662 { 663 layerDataOffset, // VkDeviceSize bufferOffset; 664 (deUint32)level.getWidth(), // deUint32 bufferRowLength; 665 (deUint32)level.getHeight(), // deUint32 bufferImageHeight; 666 { // VkImageSubresourceLayers imageSubresource; 667 VK_IMAGE_ASPECT_COLOR_BIT, 668 (deUint32)levelNdx, 669 (deUint32)layerNdx, 670 1u 671 }, 672 { 0u, 0u, 0u }, // VkOffset3D imageOffset; 673 { // VkExtent3D imageExtent; 674 (deUint32)level.getWidth(), 675 (deUint32)level.getHeight(), 676 (deUint32)level.getDepth() 677 } 678 }; 679 680 regions.push_back(layerRegion); 681 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize(); 682 } 683 } 684 } 685 686 return regions; 687 } 688 689 void TestTexture::write (deUint8* destPtr) const 690 { 691 std::vector<deUint32> offsetMultiples; 692 deUint32 levelOffset = 0; 693 694 offsetMultiples.push_back(4); 695 696 if (isCompressed()) 697 { 698 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat())); 699 700 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 701 { 702 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 703 { 704 levelOffset = getNextMultiple(offsetMultiples, levelOffset); 705 706 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx); 707 708 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize()); 709 levelOffset += compressedTex.getDataSize(); 710 } 711 } 712 } 713 else 714 { 715 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize()); 716 717 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 718 { 719 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++) 720 { 721 levelOffset = getNextMultiple(offsetMultiples, levelOffset); 722 723 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx); 724 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset); 725 726 tcu::copy(destAccess, srcAccess); 727 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize(); 728 } 729 } 730 } 731 } 732 733 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels) 734 { 735 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++) 736 TestTexture::fillWithGradient(levels[levelNdx]); 737 } 738 739 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels) 740 { 741 // Generate random compressed data and update decompressed data 742 743 de::Random random(123); 744 745 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++) 746 { 747 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx]; 748 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth()); 749 deUint8* const compressedData = (deUint8*)compressedLevel->getData(); 750 751 if (tcu::isAstcFormat(format)) 752 { 753 // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks 754 tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES, 755 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32()); 756 } 757 else 758 { 759 // Generate random compressed data 760 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++) 761 compressedData[byteNdx] = 0xFF & random.getUint32(); 762 } 763 764 m_compressedLevels.push_back(compressedLevel); 765 766 // Store decompressed data 767 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR)); 768 } 769 } 770 771 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess) 772 { 773 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat()); 774 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax); 775 } 776 777 // TestTexture1D 778 779 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width) 780 : TestTexture (format, width, 1, 1) 781 , m_texture (format, width) 782 { 783 allocateLevels(m_texture); 784 TestTexture::populateLevels(getLevelsVector(m_texture)); 785 } 786 787 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width) 788 : TestTexture (format, width, 1, 1) 789 , m_texture (tcu::getUncompressedFormat(format), width) 790 { 791 allocateLevels(m_texture); 792 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture)); 793 } 794 795 TestTexture1D::~TestTexture1D (void) 796 { 797 } 798 799 int TestTexture1D::getNumLevels (void) const 800 { 801 return m_texture.getNumLevels(); 802 } 803 804 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer) 805 { 806 DE_ASSERT(layer == 0); 807 DE_UNREF(layer); 808 return m_texture.getLevel(level); 809 } 810 811 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const 812 { 813 DE_ASSERT(layer == 0); 814 DE_UNREF(layer); 815 return m_texture.getLevel(level); 816 } 817 818 const tcu::Texture1D& TestTexture1D::getTexture (void) const 819 { 820 return m_texture; 821 } 822 823 824 // TestTexture1DArray 825 826 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize) 827 : TestTexture (format, width, 1, arraySize) 828 , m_texture (format, width, arraySize) 829 { 830 allocateLevels(m_texture); 831 TestTexture::populateLevels(getLevelsVector(m_texture)); 832 } 833 834 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize) 835 : TestTexture (format, width, 1, arraySize) 836 , m_texture (tcu::getUncompressedFormat(format), width, arraySize) 837 { 838 allocateLevels(m_texture); 839 840 std::vector<tcu::PixelBufferAccess> layers; 841 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++) 842 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++) 843 layers.push_back(getLevel(levelNdx, layerNdx)); 844 845 TestTexture::populateCompressedLevels(format, layers); 846 } 847 848 TestTexture1DArray::~TestTexture1DArray (void) 849 { 850 } 851 852 int TestTexture1DArray::getNumLevels (void) const 853 { 854 return m_texture.getNumLevels(); 855 } 856 857 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) 858 { 859 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level); 860 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize(); 861 const deUint32 layerOffset = layerSize * layer; 862 863 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 864 } 865 866 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const 867 { 868 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level); 869 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize(); 870 const deUint32 layerOffset = layerSize * layer; 871 872 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 873 } 874 875 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const 876 { 877 return m_texture; 878 } 879 880 int TestTexture1DArray::getArraySize (void) const 881 { 882 return m_texture.getNumLayers(); 883 } 884 885 886 // TestTexture2D 887 888 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height) 889 : TestTexture (format, width, height, 1) 890 , m_texture (format, width, height) 891 { 892 allocateLevels(m_texture); 893 TestTexture::populateLevels(getLevelsVector(m_texture)); 894 } 895 896 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height) 897 : TestTexture (format, width, height, 1) 898 , m_texture (tcu::getUncompressedFormat(format), width, height) 899 { 900 allocateLevels(m_texture); 901 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture)); 902 } 903 904 TestTexture2D::~TestTexture2D (void) 905 { 906 } 907 908 int TestTexture2D::getNumLevels (void) const 909 { 910 return m_texture.getNumLevels(); 911 } 912 913 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer) 914 { 915 DE_ASSERT(layer == 0); 916 DE_UNREF(layer); 917 return m_texture.getLevel(level); 918 } 919 920 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const 921 { 922 DE_ASSERT(layer == 0); 923 DE_UNREF(layer); 924 return m_texture.getLevel(level); 925 } 926 927 const tcu::Texture2D& TestTexture2D::getTexture (void) const 928 { 929 return m_texture; 930 } 931 932 933 // TestTexture2DArray 934 935 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize) 936 : TestTexture (format, width, height, arraySize) 937 , m_texture (format, width, height, arraySize) 938 { 939 allocateLevels(m_texture); 940 TestTexture::populateLevels(getLevelsVector(m_texture)); 941 } 942 943 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize) 944 : TestTexture (format, width, height, arraySize) 945 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize) 946 { 947 allocateLevels(m_texture); 948 949 std::vector<tcu::PixelBufferAccess> layers; 950 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++) 951 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++) 952 layers.push_back(getLevel(levelNdx, layerNdx)); 953 954 TestTexture::populateCompressedLevels(format, layers); 955 } 956 957 TestTexture2DArray::~TestTexture2DArray (void) 958 { 959 } 960 961 int TestTexture2DArray::getNumLevels (void) const 962 { 963 return m_texture.getNumLevels(); 964 } 965 966 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) 967 { 968 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level); 969 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 970 const deUint32 layerOffset = layerSize * layer; 971 972 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 973 } 974 975 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const 976 { 977 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level); 978 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 979 const deUint32 layerOffset = layerSize * layer; 980 981 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 982 } 983 984 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const 985 { 986 return m_texture; 987 } 988 989 int TestTexture2DArray::getArraySize (void) const 990 { 991 return m_texture.getNumLayers(); 992 } 993 994 995 // TestTexture3D 996 997 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth) 998 : TestTexture (format, width, height, depth) 999 , m_texture (format, width, height, depth) 1000 { 1001 allocateLevels(m_texture); 1002 TestTexture::populateLevels(getLevelsVector(m_texture)); 1003 } 1004 1005 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth) 1006 : TestTexture (format, width, height, depth) 1007 , m_texture (tcu::getUncompressedFormat(format), width, height, depth) 1008 { 1009 allocateLevels(m_texture); 1010 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture)); 1011 } 1012 1013 TestTexture3D::~TestTexture3D (void) 1014 { 1015 } 1016 1017 int TestTexture3D::getNumLevels (void) const 1018 { 1019 return m_texture.getNumLevels(); 1020 } 1021 1022 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer) 1023 { 1024 DE_ASSERT(layer == 0); 1025 DE_UNREF(layer); 1026 return m_texture.getLevel(level); 1027 } 1028 1029 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const 1030 { 1031 DE_ASSERT(layer == 0); 1032 DE_UNREF(layer); 1033 return m_texture.getLevel(level); 1034 } 1035 1036 const tcu::Texture3D& TestTexture3D::getTexture (void) const 1037 { 1038 return m_texture; 1039 } 1040 1041 1042 // TestTextureCube 1043 1044 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] = 1045 { 1046 tcu::CUBEFACE_POSITIVE_X, 1047 tcu::CUBEFACE_NEGATIVE_X, 1048 tcu::CUBEFACE_POSITIVE_Y, 1049 tcu::CUBEFACE_NEGATIVE_Y, 1050 tcu::CUBEFACE_POSITIVE_Z, 1051 tcu::CUBEFACE_NEGATIVE_Z 1052 }; 1053 1054 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size) 1055 : TestTexture (format, size, size, 1) 1056 , m_texture (format, size) 1057 { 1058 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 1059 { 1060 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 1061 { 1062 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx); 1063 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx])); 1064 } 1065 } 1066 } 1067 1068 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size) 1069 : TestTexture (format, size, size, 1) 1070 , m_texture (tcu::getUncompressedFormat(format), size) 1071 { 1072 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST); 1073 1074 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++) 1075 { 1076 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++) 1077 { 1078 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx); 1079 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]); 1080 } 1081 } 1082 1083 TestTexture::populateCompressedLevels(format, levels); 1084 } 1085 1086 TestTextureCube::~TestTextureCube (void) 1087 { 1088 } 1089 1090 int TestTextureCube::getNumLevels (void) const 1091 { 1092 return m_texture.getNumLevels(); 1093 } 1094 1095 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int face) 1096 { 1097 return m_texture.getLevelFace(level, (tcu::CubeFace)face); 1098 } 1099 1100 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int face) const 1101 { 1102 return m_texture.getLevelFace(level, (tcu::CubeFace)face); 1103 } 1104 1105 int TestTextureCube::getArraySize (void) const 1106 { 1107 return (int)tcu::CUBEFACE_LAST; 1108 } 1109 1110 const tcu::TextureCube& TestTextureCube::getTexture (void) const 1111 { 1112 return m_texture; 1113 } 1114 1115 // TestTextureCubeArray 1116 1117 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize) 1118 : TestTexture (format, size, size, arraySize) 1119 , m_texture (format, size, arraySize) 1120 { 1121 allocateLevels(m_texture); 1122 TestTexture::populateLevels(getLevelsVector(m_texture)); 1123 } 1124 1125 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize) 1126 : TestTexture (format, size, size, arraySize) 1127 , m_texture (tcu::getUncompressedFormat(format), size, arraySize) 1128 { 1129 DE_ASSERT(arraySize % 6 == 0); 1130 1131 allocateLevels(m_texture); 1132 1133 std::vector<tcu::PixelBufferAccess> layers; 1134 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++) 1135 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++) 1136 layers.push_back(getLevel(levelNdx, layerNdx)); 1137 1138 TestTexture::populateCompressedLevels(format, layers); 1139 } 1140 1141 TestTextureCubeArray::~TestTextureCubeArray (void) 1142 { 1143 } 1144 1145 int TestTextureCubeArray::getNumLevels (void) const 1146 { 1147 return m_texture.getNumLevels(); 1148 } 1149 1150 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) 1151 { 1152 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level); 1153 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1154 const deUint32 layerOffset = layerSize * layer; 1155 1156 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1157 } 1158 1159 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const 1160 { 1161 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level); 1162 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize(); 1163 const deUint32 layerOffset = layerSize * layer; 1164 1165 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset); 1166 } 1167 1168 int TestTextureCubeArray::getArraySize (void) const 1169 { 1170 return m_texture.getDepth(); 1171 } 1172 1173 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const 1174 { 1175 return m_texture; 1176 } 1177 1178 } // pipeline 1179 } // vkt 1180