1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Utilities for images.
34 *//*--------------------------------------------------------------------*/
36 #include "vktPipelineImageUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkMemUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkRefUtil.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "deRandom.hpp"
51 /*! Gets the next multiple of a given divisor */
52 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
54 if (value % divisor == 0)
58 return value + divisor - (value % divisor);
61 /*! Gets the next value that is multiple of all given divisors */
62 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
64 deUint32 nextMultiple = value;
65 bool nextMultipleFound = false;
69 nextMultipleFound = true;
71 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
72 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
74 if (nextMultipleFound)
77 DE_ASSERT(nextMultiple < ~((deUint32)0u));
78 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
84 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
86 if (isCompressedFormat(format))
88 VkPhysicalDeviceFeatures physicalFeatures;
89 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format);
91 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
93 if (tcu::isAstcFormat(compressedFormat))
95 if (!physicalFeatures.textureCompressionASTC_LDR)
98 else if (tcu::isEtcFormat(compressedFormat))
100 if (!physicalFeatures.textureCompressionETC2)
105 DE_FATAL("Unsupported compressed format");
109 VkFormatProperties formatProps;
110 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
112 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
115 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
117 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
121 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
122 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
123 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
132 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
133 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
134 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
141 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
144 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk,
147 deUint32 queueFamilyIndex,
148 vk::Allocator& allocator,
151 const tcu::UVec2& renderSize)
153 Move<VkBuffer> buffer;
154 de::MovePtr<Allocation> bufferAlloc;
155 Move<VkCommandPool> cmdPool;
156 Move<VkCommandBuffer> cmdBuffer;
158 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
159 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
160 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
162 // Create destination buffer
164 const VkBufferCreateInfo bufferParams =
166 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
167 DE_NULL, // const void* pNext;
168 0u, // VkBufferCreateFlags flags;
169 pixelDataSize, // VkDeviceSize size;
170 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
171 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
172 0u, // deUint32 queueFamilyIndexCount;
173 DE_NULL // const deUint32* pQueueFamilyIndices;
176 buffer = createBuffer(vk, device, &bufferParams);
177 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
178 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
181 // Create command pool and buffer
183 const VkCommandPoolCreateInfo cmdPoolParams =
185 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
186 DE_NULL, // const void* pNext;
187 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
188 queueFamilyIndex, // deUint32 queueFamilyIndex;
191 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
193 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
195 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
196 DE_NULL, // const void* pNext;
197 *cmdPool, // VkCommandPool commandPool;
198 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
199 1u // deUint32 bufferCount;
202 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
207 const VkFenceCreateInfo fenceParams =
209 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
210 DE_NULL, // const void* pNext;
211 0u // VkFenceCreateFlags flags;
214 fence = createFence(vk, device, &fenceParams);
217 // Barriers for copying image to buffer
219 const VkImageMemoryBarrier imageBarrier =
221 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
222 DE_NULL, // const void* pNext;
223 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
224 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
225 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
226 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
227 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
228 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
229 image, // VkImage image;
230 { // VkImageSubresourceRange subresourceRange;
231 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
232 0u, // deUint32 baseMipLevel;
233 1u, // deUint32 mipLevels;
234 0u, // deUint32 baseArraySlice;
235 1u // deUint32 arraySize;
239 const VkBufferMemoryBarrier bufferBarrier =
241 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
242 DE_NULL, // const void* pNext;
243 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
244 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
245 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
246 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
247 *buffer, // VkBuffer buffer;
248 0u, // VkDeviceSize offset;
249 pixelDataSize // VkDeviceSize size;
252 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
254 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
255 DE_NULL, // const void* pNext;
256 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
257 (const VkCommandBufferInheritanceInfo*)DE_NULL,
260 // Copy image to buffer
262 const VkBufferImageCopy copyRegion =
264 0u, // VkDeviceSize bufferOffset;
265 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
266 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
267 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource;
268 { 0, 0, 0 }, // VkOffset3D imageOffset;
269 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
272 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
273 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);
274 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
275 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);
276 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
278 const VkSubmitInfo submitInfo =
280 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
281 DE_NULL, // const void* pNext;
282 0u, // deUint32 waitSemaphoreCount;
283 DE_NULL, // const VkSemaphore* pWaitSemaphores;
285 1u, // deUint32 commandBufferCount;
286 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
287 0u, // deUint32 signalSemaphoreCount;
288 DE_NULL // const VkSemaphore* pSignalSemaphores;
291 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
292 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
295 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
296 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
301 void uploadTestTexture (const DeviceInterface& vk,
304 deUint32 queueFamilyIndex,
305 Allocator& allocator,
306 const TestTexture& srcTexture,
310 Move<VkBuffer> buffer;
311 de::MovePtr<Allocation> bufferAlloc;
312 Move<VkCommandPool> cmdPool;
313 Move<VkCommandBuffer> cmdBuffer;
315 std::vector<deUint32> levelDataSizes;
317 // Calculate buffer size
318 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
320 // Create source buffer
322 const VkBufferCreateInfo bufferParams =
324 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
325 DE_NULL, // const void* pNext;
326 0u, // VkBufferCreateFlags flags;
327 bufferSize, // VkDeviceSize size;
328 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
329 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
330 0u, // deUint32 queueFamilyIndexCount;
331 DE_NULL, // const deUint32* pQueueFamilyIndices;
334 buffer = createBuffer(vk, device, &bufferParams);
335 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
336 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
339 // Create command pool and buffer
341 const VkCommandPoolCreateInfo cmdPoolParams =
343 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
344 DE_NULL, // const void* pNext;
345 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
346 queueFamilyIndex, // deUint32 queueFamilyIndex;
349 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
351 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
353 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
354 DE_NULL, // const void* pNext;
355 *cmdPool, // VkCommandPool commandPool;
356 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
357 1u, // deUint32 bufferCount;
360 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
365 const VkFenceCreateInfo fenceParams =
367 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
368 DE_NULL, // const void* pNext;
369 0u // VkFenceCreateFlags flags;
372 fence = createFence(vk, device, &fenceParams);
375 // Barriers for copying buffer to image
376 const VkBufferMemoryBarrier preBufferBarrier =
378 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
379 DE_NULL, // const void* pNext;
380 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
381 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
382 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
383 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
384 *buffer, // VkBuffer buffer;
385 0u, // VkDeviceSize offset;
386 bufferSize // VkDeviceSize size;
389 const VkImageMemoryBarrier preImageBarrier =
391 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
392 DE_NULL, // const void* pNext;
393 0u, // VkAccessFlags srcAccessMask;
394 0u, // VkAccessFlags dstAccessMask;
395 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
396 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
397 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
398 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
399 destImage, // VkImage image;
400 { // VkImageSubresourceRange subresourceRange;
401 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
402 0u, // deUint32 baseMipLevel;
403 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
404 0u, // deUint32 baseArraySlice;
405 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
409 const VkImageMemoryBarrier postImageBarrier =
411 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
412 DE_NULL, // const void* pNext;
413 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
414 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
415 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
416 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
417 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
418 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
419 destImage, // VkImage image;
420 { // VkImageSubresourceRange subresourceRange;
421 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
422 0u, // deUint32 baseMipLevel;
423 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
424 0u, // deUint32 baseArraySlice;
425 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
429 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
431 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
432 DE_NULL, // const void* pNext;
433 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
434 (const VkCommandBufferInheritanceInfo*)DE_NULL,
437 const std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
440 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
441 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
443 // Copy buffer to image
444 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
445 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
446 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
447 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);
449 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
451 const VkSubmitInfo submitInfo =
453 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
454 DE_NULL, // const void* pNext;
455 0u, // deUint32 waitSemaphoreCount;
456 DE_NULL, // const VkSemaphore* pWaitSemaphores;
458 1u, // deUint32 commandBufferCount;
459 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
460 0u, // deUint32 signalSemaphoreCount;
461 DE_NULL // const VkSemaphore* pSignalSemaphores;
464 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
465 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
469 // Utilities for test textures
471 template<typename TcuTextureType>
472 void allocateLevels (TcuTextureType& texture)
474 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
475 texture.allocLevel(levelNdx);
478 template<typename TcuTextureType>
479 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
481 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
483 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
484 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
492 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
494 DE_ASSERT(width >= 1);
495 DE_ASSERT(height >= 1);
496 DE_ASSERT(depth >= 1);
504 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
506 DE_ASSERT(width >= 1);
507 DE_ASSERT(height >= 1);
508 DE_ASSERT(depth >= 1);
516 TestTexture::~TestTexture (void)
518 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
519 delete m_compressedLevels[levelNdx];
522 deUint32 TestTexture::getSize (void) const
524 std::vector<deUint32> offsetMultiples;
525 deUint32 textureSize = 0;
527 offsetMultiples.push_back(4);
528 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
530 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
532 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
534 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
535 textureSize = getNextMultiple(offsetMultiples, textureSize);
536 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
543 deUint32 TestTexture::getCompressedSize (void) const
546 throw tcu::InternalError("Texture is not compressed");
548 std::vector<deUint32> offsetMultiples;
549 deUint32 textureSize = 0;
551 offsetMultiples.push_back(4);
552 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
554 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
556 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
558 textureSize = getNextMultiple(offsetMultiples, textureSize);
559 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
566 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
568 DE_ASSERT(level >= 0 && level < getNumLevels());
569 DE_ASSERT(layer >= 0 && layer < getArraySize());
571 return *m_compressedLevels[level * getArraySize() + layer];
574 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
576 DE_ASSERT(level >= 0 && level < getNumLevels());
577 DE_ASSERT(layer >= 0 && layer < getArraySize());
579 return *m_compressedLevels[level * getArraySize() + layer];
582 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
584 std::vector<deUint32> offsetMultiples;
585 std::vector<VkBufferImageCopy> regions;
586 deUint32 layerDataOffset = 0;
588 offsetMultiples.push_back(4);
592 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
594 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
596 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
598 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
599 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat());
600 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
602 const VkBufferImageCopy layerRegion =
604 layerDataOffset, // VkDeviceSize bufferOffset;
605 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength;
606 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight;
607 { // VkImageSubresourceLayers imageSubresource;
608 VK_IMAGE_ASPECT_COLOR_BIT,
613 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
614 { // VkExtent3D imageExtent;
615 (deUint32)level.getWidth(),
616 (deUint32)level.getHeight(),
617 (deUint32)level.getDepth()
621 regions.push_back(layerRegion);
622 layerDataOffset += level.getDataSize();
628 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
630 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
632 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
634 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
636 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
638 const VkBufferImageCopy layerRegion =
640 layerDataOffset, // VkDeviceSize bufferOffset;
641 (deUint32)level.getWidth(), // deUint32 bufferRowLength;
642 (deUint32)level.getHeight(), // deUint32 bufferImageHeight;
643 { // VkImageSubresourceLayers imageSubresource;
644 VK_IMAGE_ASPECT_COLOR_BIT,
649 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
650 { // VkExtent3D imageExtent;
651 (deUint32)level.getWidth(),
652 (deUint32)level.getHeight(),
653 (deUint32)level.getDepth()
657 regions.push_back(layerRegion);
658 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
666 void TestTexture::write (deUint8* destPtr) const
668 std::vector<deUint32> offsetMultiples;
669 deUint32 levelOffset = 0;
671 offsetMultiples.push_back(4);
675 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
677 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
679 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
681 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
683 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx);
685 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
686 levelOffset += compressedTex.getDataSize();
692 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
694 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
696 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
698 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
700 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx);
701 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
703 tcu::copy(destAccess, srcAccess);
704 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
710 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
712 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
713 TestTexture::fillWithGradient(levels[levelNdx]);
716 void TestTexture::populateCompressedLevels (const tcu::CompressedTexFormat& format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
718 // Generate random compressed data and update decompressed data
720 de::Random random(123);
722 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
724 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx];
725 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
726 deUint8* const compressedData = (deUint8*)compressedLevel->getData();
728 // Generate random compressed data
729 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
730 compressedData[byteNdx] = 0xFF & random.getUint32();
732 m_compressedLevels.push_back(compressedLevel);
734 // Store decompressed data
735 compressedLevel->decompress(level, tcu::TexDecompressionParams::ASTCMODE_LDR);
739 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
741 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
742 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
747 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
748 : TestTexture (format, width, 1, 1)
749 , m_texture (format, width)
751 allocateLevels(m_texture);
752 TestTexture::populateLevels(getLevelsVector(m_texture));
755 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
756 : TestTexture (format, width, 1, 1)
757 , m_texture (tcu::getUncompressedFormat(format), width)
759 allocateLevels(m_texture);
760 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
763 TestTexture1D::~TestTexture1D (void)
767 int TestTexture1D::getNumLevels (void) const
769 return m_texture.getNumLevels();
772 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
774 DE_ASSERT(layer == 0);
775 return m_texture.getLevel(level);
778 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
780 DE_ASSERT(layer == 0);
781 return m_texture.getLevel(level);
784 const tcu::Texture1D& TestTexture1D::getTexture (void) const
790 // TestTexture1DArray
792 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
793 : TestTexture (format, width, 1, arraySize)
794 , m_texture (format, width, arraySize)
796 allocateLevels(m_texture);
797 TestTexture::populateLevels(getLevelsVector(m_texture));
800 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
801 : TestTexture (format, width, 1, arraySize)
802 , m_texture (tcu::getUncompressedFormat(format), width, arraySize)
804 allocateLevels(m_texture);
806 std::vector<tcu::PixelBufferAccess> layers;
807 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
808 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
809 layers.push_back(getLevel(levelNdx, layerNdx));
811 TestTexture::populateCompressedLevels(format, layers);
814 TestTexture1DArray::~TestTexture1DArray (void)
818 int TestTexture1DArray::getNumLevels (void) const
820 return m_texture.getNumLevels();
823 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
825 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
826 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
827 const deUint32 layerOffset = layerSize * layer;
829 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
832 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
834 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
835 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
836 const deUint32 layerOffset = layerSize * layer;
838 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
841 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
846 int TestTexture1DArray::getArraySize (void) const
848 return m_texture.getNumLayers();
854 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
855 : TestTexture (format, width, height, 1)
856 , m_texture (format, width, height)
858 allocateLevels(m_texture);
859 TestTexture::populateLevels(getLevelsVector(m_texture));
862 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
863 : TestTexture (format, width, height, 1)
864 , m_texture (tcu::getUncompressedFormat(format), width, height)
866 allocateLevels(m_texture);
867 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
870 TestTexture2D::~TestTexture2D (void)
874 int TestTexture2D::getNumLevels (void) const
876 return m_texture.getNumLevels();
879 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
881 DE_ASSERT(layer == 0);
882 return m_texture.getLevel(level);
885 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
887 DE_ASSERT(layer == 0);
888 return m_texture.getLevel(level);
891 const tcu::Texture2D& TestTexture2D::getTexture (void) const
897 // TestTexture2DArray
899 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
900 : TestTexture (format, width, height, arraySize)
901 , m_texture (format, width, height, arraySize)
903 allocateLevels(m_texture);
904 TestTexture::populateLevels(getLevelsVector(m_texture));
907 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
908 : TestTexture (format, width, height, arraySize)
909 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize)
911 allocateLevels(m_texture);
913 std::vector<tcu::PixelBufferAccess> layers;
914 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
915 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
916 layers.push_back(getLevel(levelNdx, layerNdx));
918 TestTexture::populateCompressedLevels(format, layers);
921 TestTexture2DArray::~TestTexture2DArray (void)
925 int TestTexture2DArray::getNumLevels (void) const
927 return m_texture.getNumLevels();
930 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
932 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
933 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
934 const deUint32 layerOffset = layerSize * layer;
936 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
939 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
941 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
942 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
943 const deUint32 layerOffset = layerSize * layer;
945 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
948 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
953 int TestTexture2DArray::getArraySize (void) const
955 return m_texture.getNumLayers();
961 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
962 : TestTexture (format, width, height, depth)
963 , m_texture (format, width, height, depth)
965 allocateLevels(m_texture);
966 TestTexture::populateLevels(getLevelsVector(m_texture));
969 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
970 : TestTexture (format, width, height, depth)
971 , m_texture (tcu::getUncompressedFormat(format), width, height, depth)
973 allocateLevels(m_texture);
974 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
977 TestTexture3D::~TestTexture3D (void)
981 int TestTexture3D::getNumLevels (void) const
983 return m_texture.getNumLevels();
986 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
988 DE_ASSERT(layer == 0);
989 return m_texture.getLevel(level);
992 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
994 DE_ASSERT(layer == 0);
995 return m_texture.getLevel(level);
998 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1006 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1008 tcu::CUBEFACE_POSITIVE_X,
1009 tcu::CUBEFACE_NEGATIVE_X,
1010 tcu::CUBEFACE_POSITIVE_Y,
1011 tcu::CUBEFACE_NEGATIVE_Y,
1012 tcu::CUBEFACE_POSITIVE_Z,
1013 tcu::CUBEFACE_NEGATIVE_Z
1016 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1017 : TestTexture (format, size, size, 1)
1018 , m_texture (format, size)
1020 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1022 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1024 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1025 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1030 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1031 : TestTexture (format, size, size, 1)
1032 , m_texture (tcu::getUncompressedFormat(format), size)
1034 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1036 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1038 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1040 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1041 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1045 TestTexture::populateCompressedLevels(format, levels);
1048 TestTextureCube::~TestTextureCube (void)
1052 int TestTextureCube::getNumLevels (void) const
1054 return m_texture.getNumLevels();
1057 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int face)
1059 return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1062 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int face) const
1064 return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1067 int TestTextureCube::getArraySize (void) const
1069 return (int)tcu::CUBEFACE_LAST;
1072 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1077 // TestTextureCubeArray
1079 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1080 : TestTexture (format, size, size, arraySize)
1081 , m_texture (format, size, arraySize)
1083 allocateLevels(m_texture);
1084 TestTexture::populateLevels(getLevelsVector(m_texture));
1087 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1088 : TestTexture (format, size, size, arraySize)
1089 , m_texture (tcu::getUncompressedFormat(format), size, arraySize)
1091 DE_ASSERT(arraySize % 6 == 0);
1093 allocateLevels(m_texture);
1095 std::vector<tcu::PixelBufferAccess> layers;
1096 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1097 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1098 layers.push_back(getLevel(levelNdx, layerNdx));
1100 TestTexture::populateCompressedLevels(format, layers);
1103 TestTextureCubeArray::~TestTextureCubeArray (void)
1107 int TestTextureCubeArray::getNumLevels (void) const
1109 return m_texture.getNumLevels();
1112 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1114 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1115 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1116 const deUint32 layerOffset = layerSize * layer;
1118 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1121 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1123 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1124 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1125 const deUint32 layerOffset = layerSize * layer;
1127 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1130 int TestTextureCubeArray::getArraySize (void) const
1132 return m_texture.getDepth();
1135 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const