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