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 M */
53 static int getNextMultiple(deUint32 value)
59 return value + M - (value % M);
62 static int getNextMultiple (deUint32 M, deUint32 value)
68 return value + M - (value % M);
72 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
74 if (isCompressedFormat(format))
76 VkPhysicalDeviceFeatures physicalFeatures;
77 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format);
79 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
81 if (tcu::isAstcFormat(compressedFormat))
83 if (!physicalFeatures.textureCompressionASTC_LDR)
86 else if (tcu::isEtcFormat(compressedFormat))
88 if (!physicalFeatures.textureCompressionETC2)
93 DE_FATAL("Unsupported compressed format");
97 VkFormatProperties formatProps;
98 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
100 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
103 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
105 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
109 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
110 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
111 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
120 case BORDER_COLOR_OPAQUE_BLACK: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
121 case BORDER_COLOR_OPAQUE_WHITE: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
122 case BORDER_COLOR_TRANSPARENT_BLACK: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
129 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
132 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk,
135 deUint32 queueFamilyIndex,
136 vk::Allocator& allocator,
139 const tcu::IVec2& renderSize)
141 Move<VkBuffer> buffer;
142 de::MovePtr<Allocation> bufferAlloc;
143 Move<VkCommandPool> cmdPool;
144 Move<VkCommandBuffer> cmdBuffer;
146 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
147 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
148 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
150 // Create destination buffer
152 const VkBufferCreateInfo bufferParams =
154 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
155 DE_NULL, // const void* pNext;
156 0u, // VkBufferCreateFlags flags;
157 pixelDataSize, // VkDeviceSize size;
158 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
159 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
160 0u, // deUint32 queueFamilyIndexCount;
161 DE_NULL // const deUint32* pQueueFamilyIndices;
164 buffer = createBuffer(vk, device, &bufferParams);
165 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
166 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
169 // Create command pool and buffer
171 const VkCommandPoolCreateInfo cmdPoolParams =
173 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
174 DE_NULL, // const void* pNext;
175 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
176 queueFamilyIndex, // deUint32 queueFamilyIndex;
179 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
181 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
183 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
184 DE_NULL, // const void* pNext;
185 *cmdPool, // VkCommandPool commandPool;
186 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
187 1u // deUint32 bufferCount;
190 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
195 const VkFenceCreateInfo fenceParams =
197 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
198 DE_NULL, // const void* pNext;
199 0u // VkFenceCreateFlags flags;
202 fence = createFence(vk, device, &fenceParams);
205 // Barriers for copying image to buffer
207 const VkImageMemoryBarrier imageBarrier =
209 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
210 DE_NULL, // const void* pNext;
211 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
212 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
213 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
214 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
215 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
216 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
217 image, // VkImage image;
218 { // VkImageSubresourceRange subresourceRange;
219 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
220 0u, // deUint32 baseMipLevel;
221 1u, // deUint32 mipLevels;
222 0u, // deUint32 baseArraySlice;
223 1u // deUint32 arraySize;
227 const VkBufferMemoryBarrier bufferBarrier =
229 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
230 DE_NULL, // const void* pNext;
231 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
232 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
233 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
234 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
235 *buffer, // VkBuffer buffer;
236 0u, // VkDeviceSize offset;
237 pixelDataSize // VkDeviceSize size;
240 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
242 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
243 DE_NULL, // const void* pNext;
244 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
245 DE_NULL, // VkRenderPass renderPass;
246 0u, // deUint32 subpass;
247 DE_NULL, // VkFramebuffer framebuffer;
248 false, // VkBool32 occlusionQueryEnable;
249 0u, // VkQueryControlFlags queryFlags;
250 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
253 const void* const imageBarrierPtr = &imageBarrier;
254 const void* const bufferBarrierPtr = &bufferBarrier;
256 // Copy image to buffer
258 const VkBufferImageCopy copyRegion =
260 0u, // VkDeviceSize bufferOffset;
261 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
262 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
263 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource;
264 { 0, 0, 0 }, // VkOffset3D imageOffset;
265 { renderSize.x(), renderSize.y(), 1 } // VkExtent3D imageExtent;
268 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
269 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 1, &imageBarrierPtr);
270 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
271 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &bufferBarrierPtr);
272 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
274 const VkSubmitInfo submitInfo =
276 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
277 DE_NULL, // const void* pNext;
278 0u, // deUint32 waitSemaphoreCount;
279 DE_NULL, // const VkSemaphore* pWaitSemaphores;
280 1u, // deUint32 commandBufferCount;
281 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
282 0u, // deUint32 signalSemaphoreCount;
283 DE_NULL // const VkSemaphore* pSignalSemaphores;
286 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
287 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
290 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
291 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
296 void uploadTestTexture (const DeviceInterface& vk,
299 deUint32 queueFamilyIndex,
300 Allocator& allocator,
301 const TestTexture& srcTexture,
305 Move<VkBuffer> buffer;
306 de::MovePtr<Allocation> bufferAlloc;
307 Move<VkCommandPool> cmdPool;
308 Move<VkCommandBuffer> cmdBuffer;
310 std::vector<deUint32> levelDataSizes;
312 // Calculate buffer size
313 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
315 // Create source buffer
317 const VkBufferCreateInfo bufferParams =
319 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
320 DE_NULL, // const void* pNext;
321 0u, // VkBufferCreateFlags flags;
322 bufferSize, // VkDeviceSize size;
323 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
324 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
325 0u, // deUint32 queueFamilyIndexCount;
326 DE_NULL, // const deUint32* pQueueFamilyIndices;
329 buffer = createBuffer(vk, device, &bufferParams);
330 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
331 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
334 // Create command pool and buffer
336 const VkCommandPoolCreateInfo cmdPoolParams =
338 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
339 DE_NULL, // const void* pNext;
340 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
341 queueFamilyIndex, // deUint32 queueFamilyIndex;
344 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
346 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
348 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
349 DE_NULL, // const void* pNext;
350 *cmdPool, // VkCommandPool commandPool;
351 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
352 1u, // deUint32 bufferCount;
355 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
360 const VkFenceCreateInfo fenceParams =
362 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
363 DE_NULL, // const void* pNext;
364 0u // VkFenceCreateFlags flags;
367 fence = createFence(vk, device, &fenceParams);
370 // Barriers for copying buffer to image
371 const VkBufferMemoryBarrier preBufferBarrier =
373 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
374 DE_NULL, // const void* pNext;
375 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
376 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
377 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
378 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
379 *buffer, // VkBuffer buffer;
380 0u, // VkDeviceSize offset;
381 bufferSize // VkDeviceSize size;
384 const VkImageMemoryBarrier preImageBarrier =
386 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
387 DE_NULL, // const void* pNext;
388 0u, // VkAccessFlags srcAccessMask;
389 0u, // VkAccessFlags dstAccessMask;
390 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
391 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
392 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
393 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
394 destImage, // VkImage image;
395 { // VkImageSubresourceRange subresourceRange;
396 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
397 0u, // deUint32 baseMipLevel;
398 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
399 0u, // deUint32 baseArraySlice;
400 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
404 const VkImageMemoryBarrier postImageBarrier =
406 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
407 DE_NULL, // const void* pNext;
408 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
409 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
410 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
411 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
412 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
413 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
414 destImage, // VkImage image;
415 { // VkImageSubresourceRange subresourceRange;
416 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
417 0u, // deUint32 baseMipLevel;
418 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
419 0u, // deUint32 baseArraySlice;
420 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
424 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
426 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
427 DE_NULL, // const void* pNext;
428 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
429 DE_NULL, // VkRenderPass renderPass;
430 0u, // deUint32 subpass;
431 DE_NULL, // VkFramebuffer framebuffer;
432 false, // VkBool32 occlusionQueryEnable;
433 0u, // VkQueryControlFlags queryFlags;
434 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
437 const void* preCopyBarriers[2] =
443 const void* const postCopyBarrier = &postImageBarrier;
444 const std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
447 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
448 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
450 // Copy buffer to image
451 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
452 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 2, preCopyBarriers);
453 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
454 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &postCopyBarrier);
456 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
458 const VkSubmitInfo submitInfo =
460 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
461 DE_NULL, // const void* pNext;
462 0u, // deUint32 waitSemaphoreCount;
463 DE_NULL, // const VkSemaphore* pWaitSemaphores;
464 1u, // deUint32 commandBufferCount;
465 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
466 0u, // deUint32 signalSemaphoreCount;
467 DE_NULL // const VkSemaphore* pSignalSemaphores;
470 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
471 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
475 // Utilities for test textures
477 template<typename TcuTextureType>
478 void allocateLevels (TcuTextureType& texture)
480 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
481 texture.allocLevel(levelNdx);
484 template<typename TcuTextureType>
485 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
487 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
489 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
490 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
498 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
500 DE_ASSERT(width >= 1);
501 DE_ASSERT(height >= 1);
502 DE_ASSERT(depth >= 1);
510 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
512 DE_ASSERT(width >= 1);
513 DE_ASSERT(height >= 1);
514 DE_ASSERT(depth >= 1);
522 TestTexture::~TestTexture (void)
524 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
525 delete m_compressedLevels[levelNdx];
528 deUint32 TestTexture::getSize (void) const
530 deUint32 textureSize = 0;
532 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
534 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
536 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
537 textureSize = getNextMultiple<4>(textureSize);
538 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
545 deUint32 TestTexture::getCompressedSize (void) const
548 throw tcu::InternalError("Texture is not compressed");
550 deUint32 textureSize = 0;
552 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
554 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
556 textureSize = getNextMultiple<4>(textureSize);
557 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
564 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
566 DE_ASSERT(level >= 0 && level < getNumLevels());
567 DE_ASSERT(layer >= 0 && layer < getArraySize());
569 return *m_compressedLevels[level * getArraySize() + layer];
572 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
574 DE_ASSERT(level >= 0 && level < getNumLevels());
575 DE_ASSERT(layer >= 0 && layer < getArraySize());
577 return *m_compressedLevels[level * getArraySize() + layer];
580 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
582 std::vector<VkBufferImageCopy> regions;
583 deUint32 layerDataOffset = 0;
587 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
589 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
591 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
592 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat());
593 layerDataOffset = getNextMultiple<4>(layerDataOffset);
595 const VkBufferImageCopy layerRegion =
597 layerDataOffset, // VkDeviceSize bufferOffset;
598 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength;
599 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight;
600 { // VkImageSubresourceLayers imageSubresource;
601 VK_IMAGE_ASPECT_COLOR_BIT,
606 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
607 { // VkExtent3D imageExtent;
614 regions.push_back(layerRegion);
615 layerDataOffset += level.getDataSize();
621 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
623 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
625 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
627 layerDataOffset = getNextMultiple<4>(layerDataOffset);
629 const VkBufferImageCopy layerRegion =
631 layerDataOffset, // VkDeviceSize bufferOffset;
632 (deUint32)level.getWidth(), // deUint32 bufferRowLength;
633 (deUint32)level.getHeight(), // deUint32 bufferImageHeight;
634 { // VkImageSubresourceLayers imageSubresource;
635 VK_IMAGE_ASPECT_COLOR_BIT,
640 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
641 { // VkExtent3D imageExtent;
648 regions.push_back(layerRegion);
649 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
657 void TestTexture::write (deUint8* destPtr) const
659 deUint32 levelOffset = 0;
663 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
665 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
667 levelOffset = getNextMultiple<4>(levelOffset);
669 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx);
671 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
672 levelOffset += compressedTex.getDataSize();
678 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
680 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
682 levelOffset = getNextMultiple<4>(levelOffset);
684 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx);
685 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
687 tcu::copy(destAccess, srcAccess);
688 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
694 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
696 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
697 TestTexture::fillWithGradient(levels[levelNdx]);
700 void TestTexture::populateCompressedLevels (const tcu::CompressedTexFormat& format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
702 // Generate random compressed data and update decompressed data
704 de::Random random(123);
706 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
708 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx];
709 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
710 deUint8* const compressedData = (deUint8*)compressedLevel->getData();
712 // Generate random compressed data
713 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
714 compressedData[byteNdx] = 0xFF & random.getUint32();
716 m_compressedLevels.push_back(compressedLevel);
718 // Store decompressed data
719 compressedLevel->decompress(level);
723 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
725 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
726 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
731 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
732 : TestTexture (format, width, 1, 1)
733 , m_texture (format, width)
735 allocateLevels(m_texture);
736 TestTexture::populateLevels(getLevelsVector(m_texture));
739 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
740 : TestTexture (format, width, 1, 1)
741 , m_texture (tcu::getUncompressedFormat(format), width)
743 allocateLevels(m_texture);
744 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
747 TestTexture1D::~TestTexture1D (void)
751 int TestTexture1D::getNumLevels (void) const
753 return m_texture.getNumLevels();
756 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
758 DE_ASSERT(layer == 0);
759 return m_texture.getLevel(level);
762 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
764 DE_ASSERT(layer == 0);
765 return m_texture.getLevel(level);
768 const tcu::Texture1D& TestTexture1D::getTexture (void) const
774 // TestTexture1DArray
776 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
777 : TestTexture (format, width, 1, arraySize)
778 , m_texture (format, width, arraySize)
780 allocateLevels(m_texture);
781 TestTexture::populateLevels(getLevelsVector(m_texture));
784 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
785 : TestTexture (format, width, 1, arraySize)
786 , m_texture (tcu::getUncompressedFormat(format), width, arraySize)
788 allocateLevels(m_texture);
790 std::vector<tcu::PixelBufferAccess> layers;
791 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
792 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
793 layers.push_back(getLevel(levelNdx, layerNdx));
795 TestTexture::populateCompressedLevels(format, layers);
798 TestTexture1DArray::~TestTexture1DArray (void)
802 int TestTexture1DArray::getNumLevels (void) const
804 return m_texture.getNumLevels();
807 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
809 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
810 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
811 const deUint32 layerOffset = layerSize * layer;
813 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
816 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
818 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
819 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
820 const deUint32 layerOffset = layerSize * layer;
822 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
825 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
830 int TestTexture1DArray::getArraySize (void) const
832 return m_texture.getNumLayers();
838 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
839 : TestTexture (format, width, height, 1)
840 , m_texture (format, width, height)
842 allocateLevels(m_texture);
843 TestTexture::populateLevels(getLevelsVector(m_texture));
846 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
847 : TestTexture (format, width, height, 1)
848 , m_texture (tcu::getUncompressedFormat(format), width, height)
850 allocateLevels(m_texture);
851 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
854 TestTexture2D::~TestTexture2D (void)
858 int TestTexture2D::getNumLevels (void) const
860 return m_texture.getNumLevels();
863 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
865 DE_ASSERT(layer == 0);
866 return m_texture.getLevel(level);
869 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
871 DE_ASSERT(layer == 0);
872 return m_texture.getLevel(level);
875 const tcu::Texture2D& TestTexture2D::getTexture (void) const
881 // TestTexture2DArray
883 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
884 : TestTexture (format, width, height, arraySize)
885 , m_texture (format, width, height, arraySize)
887 allocateLevels(m_texture);
888 TestTexture::populateLevels(getLevelsVector(m_texture));
891 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
892 : TestTexture (format, width, height, arraySize)
893 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize)
895 allocateLevels(m_texture);
897 std::vector<tcu::PixelBufferAccess> layers;
898 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
899 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
900 layers.push_back(getLevel(levelNdx, layerNdx));
902 TestTexture::populateCompressedLevels(format, layers);
905 TestTexture2DArray::~TestTexture2DArray (void)
909 int TestTexture2DArray::getNumLevels (void) const
911 return m_texture.getNumLevels();
914 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
916 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
917 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
918 const deUint32 layerOffset = layerSize * layer;
920 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
923 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
925 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
926 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
927 const deUint32 layerOffset = layerSize * layer;
929 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
932 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
937 int TestTexture2DArray::getArraySize (void) const
939 return m_texture.getNumLayers();
945 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
946 : TestTexture (format, width, height, depth)
947 , m_texture (format, width, height, depth)
949 allocateLevels(m_texture);
950 TestTexture::populateLevels(getLevelsVector(m_texture));
953 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
954 : TestTexture (format, width, height, depth)
955 , m_texture (tcu::getUncompressedFormat(format), width, height, depth)
957 allocateLevels(m_texture);
958 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
961 TestTexture3D::~TestTexture3D (void)
965 int TestTexture3D::getNumLevels (void) const
967 return m_texture.getNumLevels();
970 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
972 DE_ASSERT(layer == 0);
973 return m_texture.getLevel(level);
976 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
978 DE_ASSERT(layer == 0);
979 return m_texture.getLevel(level);
982 const tcu::Texture3D& TestTexture3D::getTexture (void) const
990 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
992 tcu::CUBEFACE_POSITIVE_X,
993 tcu::CUBEFACE_NEGATIVE_X,
994 tcu::CUBEFACE_POSITIVE_Y,
995 tcu::CUBEFACE_NEGATIVE_Y,
996 tcu::CUBEFACE_POSITIVE_Z,
997 tcu::CUBEFACE_NEGATIVE_Z
1000 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1001 : TestTexture (format, size, size, 1)
1002 , m_texture (format, size)
1004 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1006 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1008 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1009 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1014 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1015 : TestTexture (format, size, size, 1)
1016 , m_texture (tcu::getUncompressedFormat(format), size)
1018 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
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 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1029 TestTexture::populateCompressedLevels(format, levels);
1032 TestTextureCube::~TestTextureCube (void)
1036 int TestTextureCube::getNumLevels (void) const
1038 return m_texture.getNumLevels();
1041 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int face)
1043 return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1046 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int face) const
1048 return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1051 int TestTextureCube::getArraySize (void) const
1053 return (int)tcu::CUBEFACE_LAST;
1056 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1061 // TestTextureCubeArray
1063 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1064 : TestTexture (format, size, size, arraySize)
1065 , m_texture (format, size, arraySize)
1067 allocateLevels(m_texture);
1068 TestTexture::populateLevels(getLevelsVector(m_texture));
1071 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1072 : TestTexture (format, size, size, arraySize)
1073 , m_texture (tcu::getUncompressedFormat(format), size, arraySize)
1075 DE_ASSERT(arraySize % 6 == 0);
1077 allocateLevels(m_texture);
1079 std::vector<tcu::PixelBufferAccess> layers;
1080 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1081 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1082 layers.push_back(getLevel(levelNdx, layerNdx));
1084 TestTexture::populateCompressedLevels(format, layers);
1087 TestTextureCubeArray::~TestTextureCubeArray (void)
1091 int TestTextureCubeArray::getNumLevels (void) const
1093 return m_texture.getNumLevels();
1096 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1098 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1099 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1100 const deUint32 layerOffset = layerSize * layer;
1102 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1105 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1107 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1108 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1109 const deUint32 layerOffset = layerSize * layer;
1111 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1114 int TestTextureCubeArray::getArraySize (void) const
1116 return m_texture.getDepth();
1119 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const