1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Utilities for images.
23 *//*--------------------------------------------------------------------*/
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"
41 /*! Gets the next multiple of a given divisor */
42 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
44 if (value % divisor == 0)
48 return value + divisor - (value % divisor);
51 /*! Gets the next value that is multiple of all given divisors */
52 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
54 deUint32 nextMultiple = value;
55 bool nextMultipleFound = false;
59 nextMultipleFound = true;
61 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
62 nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
64 if (nextMultipleFound)
67 DE_ASSERT(nextMultiple < ~((deUint32)0u));
68 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
74 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
76 if (isCompressedFormat(format))
78 VkPhysicalDeviceFeatures physicalFeatures;
79 const tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(format);
81 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
83 if (tcu::isAstcFormat(compressedFormat))
85 if (!physicalFeatures.textureCompressionASTC_LDR)
88 else if (tcu::isEtcFormat(compressedFormat))
90 if (!physicalFeatures.textureCompressionETC2)
95 DE_FATAL("Unsupported compressed format");
99 VkFormatProperties formatProps;
100 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
102 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
105 // \todo [2016-01-21 pyry] Update this to just rely on vkDefs.hpp once
106 // CTS has been updated to 1.0.2.
109 VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
112 bool isLinearFilteringSupported (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling tiling)
114 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
115 const VkFormatFeatureFlags formatFeatures = tiling == VK_IMAGE_TILING_LINEAR
116 ? formatProperties.linearTilingFeatures
117 : formatProperties.optimalTilingFeatures;
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;
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.
138 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
140 if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
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;
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;
164 return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
167 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk,
170 deUint32 queueFamilyIndex,
171 vk::Allocator& allocator,
174 const tcu::UVec2& renderSize)
176 Move<VkBuffer> buffer;
177 de::MovePtr<Allocation> bufferAlloc;
178 Move<VkCommandPool> cmdPool;
179 Move<VkCommandBuffer> cmdBuffer;
181 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
182 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
183 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
185 // Create destination buffer
187 const VkBufferCreateInfo bufferParams =
189 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
190 DE_NULL, // const void* pNext;
191 0u, // VkBufferCreateFlags flags;
192 pixelDataSize, // VkDeviceSize size;
193 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
194 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
195 0u, // deUint32 queueFamilyIndexCount;
196 DE_NULL // const deUint32* pQueueFamilyIndices;
199 buffer = createBuffer(vk, device, &bufferParams);
200 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
201 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
204 // Create command pool and buffer
206 const VkCommandPoolCreateInfo cmdPoolParams =
208 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
209 DE_NULL, // const void* pNext;
210 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
211 queueFamilyIndex, // deUint32 queueFamilyIndex;
214 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
216 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
218 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
219 DE_NULL, // const void* pNext;
220 *cmdPool, // VkCommandPool commandPool;
221 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
222 1u // deUint32 bufferCount;
225 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
230 const VkFenceCreateInfo fenceParams =
232 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
233 DE_NULL, // const void* pNext;
234 0u // VkFenceCreateFlags flags;
237 fence = createFence(vk, device, &fenceParams);
240 // Barriers for copying image to buffer
242 const VkImageMemoryBarrier imageBarrier =
244 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
245 DE_NULL, // const void* pNext;
246 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
247 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
248 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
249 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
250 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
251 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
252 image, // VkImage image;
253 { // VkImageSubresourceRange subresourceRange;
254 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
255 0u, // deUint32 baseMipLevel;
256 1u, // deUint32 mipLevels;
257 0u, // deUint32 baseArraySlice;
258 1u // deUint32 arraySize;
262 const VkBufferMemoryBarrier bufferBarrier =
264 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
265 DE_NULL, // const void* pNext;
266 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
267 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
268 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
269 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
270 *buffer, // VkBuffer buffer;
271 0u, // VkDeviceSize offset;
272 pixelDataSize // VkDeviceSize size;
275 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
277 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
278 DE_NULL, // const void* pNext;
279 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
280 (const VkCommandBufferInheritanceInfo*)DE_NULL,
283 // Copy image to buffer
285 const VkBufferImageCopy copyRegion =
287 0u, // VkDeviceSize bufferOffset;
288 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
289 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
290 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource;
291 { 0, 0, 0 }, // VkOffset3D imageOffset;
292 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
295 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
296 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
297 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
298 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
299 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
301 const VkSubmitInfo submitInfo =
303 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
304 DE_NULL, // const void* pNext;
305 0u, // deUint32 waitSemaphoreCount;
306 DE_NULL, // const VkSemaphore* pWaitSemaphores;
308 1u, // deUint32 commandBufferCount;
309 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
310 0u, // deUint32 signalSemaphoreCount;
311 DE_NULL // const VkSemaphore* pSignalSemaphores;
314 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
315 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
318 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
319 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
327 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat)
329 VkImageAspectFlags imageAspectFlags = 0;
331 if (tcu::hasDepthComponent(textureFormat.order))
332 imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
334 if (tcu::hasStencilComponent(textureFormat.order))
335 imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
337 if (imageAspectFlags == 0)
338 imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
340 return imageAspectFlags;
345 void uploadTestTextureInternal (const DeviceInterface& vk,
348 deUint32 queueFamilyIndex,
349 Allocator& allocator,
350 const TestTexture& srcTexture,
354 Move<VkBuffer> buffer;
355 de::MovePtr<Allocation> bufferAlloc;
356 Move<VkCommandPool> cmdPool;
357 Move<VkCommandBuffer> cmdBuffer;
359 const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(srcTexture.getTextureFormat());
361 // Calculate buffer size
362 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
364 // Create source buffer
366 const VkBufferCreateInfo bufferParams =
368 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
369 DE_NULL, // const void* pNext;
370 0u, // VkBufferCreateFlags flags;
371 bufferSize, // VkDeviceSize size;
372 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
373 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
374 0u, // deUint32 queueFamilyIndexCount;
375 DE_NULL, // const deUint32* pQueueFamilyIndices;
378 buffer = createBuffer(vk, device, &bufferParams);
379 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
380 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
383 // Create command pool and buffer
385 const VkCommandPoolCreateInfo cmdPoolParams =
387 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
388 DE_NULL, // const void* pNext;
389 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
390 queueFamilyIndex, // deUint32 queueFamilyIndex;
393 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
395 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
397 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
398 DE_NULL, // const void* pNext;
399 *cmdPool, // VkCommandPool commandPool;
400 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
401 1u, // deUint32 bufferCount;
404 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
409 const VkFenceCreateInfo fenceParams =
411 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
412 DE_NULL, // const void* pNext;
413 0u // VkFenceCreateFlags flags;
416 fence = createFence(vk, device, &fenceParams);
419 // Barriers for copying buffer to image
420 const VkBufferMemoryBarrier preBufferBarrier =
422 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
423 DE_NULL, // const void* pNext;
424 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
425 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
426 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
427 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
428 *buffer, // VkBuffer buffer;
429 0u, // VkDeviceSize offset;
430 bufferSize // VkDeviceSize size;
433 const VkImageMemoryBarrier preImageBarrier =
435 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
436 DE_NULL, // const void* pNext;
437 0u, // VkAccessFlags srcAccessMask;
438 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
439 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
440 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
441 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
442 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
443 destImage, // VkImage image;
444 { // VkImageSubresourceRange subresourceRange;
445 imageAspectFlags, // VkImageAspectFlags aspectMask;
446 0u, // deUint32 baseMipLevel;
447 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
448 0u, // deUint32 baseArraySlice;
449 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
453 const VkImageMemoryBarrier postImageBarrier =
455 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
456 DE_NULL, // const void* pNext;
457 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
458 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
459 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
460 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
461 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
462 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
463 destImage, // VkImage image;
464 { // VkImageSubresourceRange subresourceRange;
465 imageAspectFlags, // VkImageAspectFlags aspectMask;
466 0u, // deUint32 baseMipLevel;
467 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
468 0u, // deUint32 baseArraySlice;
469 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
473 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
475 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
476 DE_NULL, // const void* pNext;
477 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
478 (const VkCommandBufferInheritanceInfo*)DE_NULL,
481 const std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
484 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
485 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
487 // Copy buffer to image
488 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
489 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
490 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
491 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);
493 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
495 const VkSubmitInfo submitInfo =
497 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
498 DE_NULL, // const void* pNext;
499 0u, // deUint32 waitSemaphoreCount;
500 DE_NULL, // const VkSemaphore* pWaitSemaphores;
502 1u, // deUint32 commandBufferCount;
503 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
504 0u, // deUint32 signalSemaphoreCount;
505 DE_NULL // const VkSemaphore* pSignalSemaphores;
508 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
509 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
512 void uploadTestTexture (const DeviceInterface& vk,
515 deUint32 queueFamilyIndex,
516 Allocator& allocator,
517 const TestTexture& srcTexture,
520 if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
522 if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
524 tcu::TextureFormat format;
525 switch (srcTexture.getTextureFormat().type) {
526 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
527 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
529 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
530 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
532 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
533 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
538 de::MovePtr<TestTexture> depthTexture = srcTexture.copy(format);
539 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *depthTexture, destImage);
542 if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
544 de::MovePtr<TestTexture> stencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
545 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *stencilTexture, destImage);
549 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, destImage);
552 // Utilities for test textures
554 template<typename TcuTextureType>
555 void allocateLevels (TcuTextureType& texture)
557 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
558 texture.allocLevel(levelNdx);
561 template<typename TcuTextureType>
562 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
564 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
566 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
567 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
574 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
576 DE_ASSERT(width >= 1);
577 DE_ASSERT(height >= 1);
578 DE_ASSERT(depth >= 1);
586 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
588 DE_ASSERT(width >= 1);
589 DE_ASSERT(height >= 1);
590 DE_ASSERT(depth >= 1);
598 TestTexture::~TestTexture (void)
600 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
601 delete m_compressedLevels[levelNdx];
604 deUint32 TestTexture::getSize (void) const
606 std::vector<deUint32> offsetMultiples;
607 deUint32 textureSize = 0;
609 offsetMultiples.push_back(4);
610 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
612 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
614 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
616 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
617 textureSize = getNextMultiple(offsetMultiples, textureSize);
618 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
625 deUint32 TestTexture::getCompressedSize (void) const
628 throw tcu::InternalError("Texture is not compressed");
630 std::vector<deUint32> offsetMultiples;
631 deUint32 textureSize = 0;
633 offsetMultiples.push_back(4);
634 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
636 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
638 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
640 textureSize = getNextMultiple(offsetMultiples, textureSize);
641 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
648 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
650 DE_ASSERT(level >= 0 && level < getNumLevels());
651 DE_ASSERT(layer >= 0 && layer < getArraySize());
653 return *m_compressedLevels[level * getArraySize() + layer];
656 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
658 DE_ASSERT(level >= 0 && level < getNumLevels());
659 DE_ASSERT(layer >= 0 && layer < getArraySize());
661 return *m_compressedLevels[level * getArraySize() + layer];
664 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
666 std::vector<deUint32> offsetMultiples;
667 std::vector<VkBufferImageCopy> regions;
668 deUint32 layerDataOffset = 0;
670 offsetMultiples.push_back(4);
674 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
676 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
678 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
680 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
681 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat());
682 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
684 const VkBufferImageCopy layerRegion =
686 layerDataOffset, // VkDeviceSize bufferOffset;
687 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength;
688 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight;
689 { // VkImageSubresourceLayers imageSubresource;
690 VK_IMAGE_ASPECT_COLOR_BIT,
695 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
696 { // VkExtent3D imageExtent;
697 (deUint32)level.getWidth(),
698 (deUint32)level.getHeight(),
699 (deUint32)level.getDepth()
703 regions.push_back(layerRegion);
704 layerDataOffset += level.getDataSize();
710 std::vector<VkImageAspectFlags> imageAspects;
711 tcu::TextureFormat textureFormat = getTextureFormat();
713 if (tcu::hasDepthComponent(textureFormat.order))
714 imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
716 if (tcu::hasStencilComponent(textureFormat.order))
717 imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
719 if (imageAspects.empty())
720 imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
722 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
724 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
726 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
728 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
730 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
732 for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
734 const VkBufferImageCopy layerRegion =
736 layerDataOffset, // VkDeviceSize bufferOffset;
737 (deUint32)level.getWidth(), // deUint32 bufferRowLength;
738 (deUint32)level.getHeight(), // deUint32 bufferImageHeight;
739 { // VkImageSubresourceLayers imageSubresource;
740 imageAspects[aspectIndex],
745 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
746 { // VkExtent3D imageExtent;
747 (deUint32)level.getWidth(),
748 (deUint32)level.getHeight(),
749 (deUint32)level.getDepth()
753 regions.push_back(layerRegion);
755 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
763 void TestTexture::write (deUint8* destPtr) const
765 std::vector<deUint32> offsetMultiples;
766 deUint32 levelOffset = 0;
768 offsetMultiples.push_back(4);
772 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
774 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
776 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
778 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
780 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx);
782 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
783 levelOffset += compressedTex.getDataSize();
789 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
791 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
793 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
795 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
797 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx);
798 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
800 tcu::copy(destAccess, srcAccess);
801 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
807 void TestTexture::copyToTexture (TestTexture& destTexture) const
809 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
810 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
811 tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx));
814 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
816 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
817 TestTexture::fillWithGradient(levels[levelNdx]);
820 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
822 // Generate random compressed data and update decompressed data
824 de::Random random(123);
826 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
828 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx];
829 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
830 deUint8* const compressedData = (deUint8*)compressedLevel->getData();
832 if (tcu::isAstcFormat(format))
834 // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
835 tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
836 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
840 // Generate random compressed data
841 // Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
842 if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
843 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
844 compressedData[byteNdx] = 0xFF & random.getUint32();
847 m_compressedLevels.push_back(compressedLevel);
849 // Store decompressed data
850 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
854 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
856 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
857 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
862 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
863 : TestTexture (format, width, 1, 1)
864 , m_texture (format, width)
866 allocateLevels(m_texture);
867 TestTexture::populateLevels(getLevelsVector(m_texture));
870 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
871 : TestTexture (format, width, 1, 1)
872 , m_texture (tcu::getUncompressedFormat(format), width)
874 allocateLevels(m_texture);
875 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
878 TestTexture1D::~TestTexture1D (void)
882 int TestTexture1D::getNumLevels (void) const
884 return m_texture.getNumLevels();
887 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
889 DE_ASSERT(layer == 0);
891 return m_texture.getLevel(level);
894 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
896 DE_ASSERT(layer == 0);
898 return m_texture.getLevel(level);
901 const tcu::Texture1D& TestTexture1D::getTexture (void) const
906 tcu::Texture1D& TestTexture1D::getTexture (void)
911 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const
913 DE_ASSERT(!isCompressed());
915 de::MovePtr<TestTexture> texture (new TestTexture1D(format, m_texture.getWidth()));
917 copyToTexture(*texture);
922 // TestTexture1DArray
924 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
925 : TestTexture (format, width, 1, arraySize)
926 , m_texture (format, width, arraySize)
928 allocateLevels(m_texture);
929 TestTexture::populateLevels(getLevelsVector(m_texture));
932 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
933 : TestTexture (format, width, 1, arraySize)
934 , m_texture (tcu::getUncompressedFormat(format), width, arraySize)
936 allocateLevels(m_texture);
938 std::vector<tcu::PixelBufferAccess> layers;
939 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
940 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
941 layers.push_back(getLevel(levelNdx, layerNdx));
943 TestTexture::populateCompressedLevels(format, layers);
946 TestTexture1DArray::~TestTexture1DArray (void)
950 int TestTexture1DArray::getNumLevels (void) const
952 return m_texture.getNumLevels();
955 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
957 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
958 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
959 const deUint32 layerOffset = layerSize * layer;
961 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
964 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
966 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
967 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
968 const deUint32 layerOffset = layerSize * layer;
970 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
973 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
978 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
983 int TestTexture1DArray::getArraySize (void) const
985 return m_texture.getNumLayers();
988 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const
990 DE_ASSERT(!isCompressed());
992 de::MovePtr<TestTexture> texture (new TestTexture1DArray(format, m_texture.getWidth(), getArraySize()));
994 copyToTexture(*texture);
1001 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
1002 : TestTexture (format, width, height, 1)
1003 , m_texture (format, width, height)
1005 allocateLevels(m_texture);
1006 TestTexture::populateLevels(getLevelsVector(m_texture));
1009 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
1010 : TestTexture (format, width, height, 1)
1011 , m_texture (tcu::getUncompressedFormat(format), width, height)
1013 allocateLevels(m_texture);
1014 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1017 TestTexture2D::~TestTexture2D (void)
1021 int TestTexture2D::getNumLevels (void) const
1023 return m_texture.getNumLevels();
1026 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
1028 DE_ASSERT(layer == 0);
1030 return m_texture.getLevel(level);
1033 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1035 DE_ASSERT(layer == 0);
1037 return m_texture.getLevel(level);
1040 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1045 tcu::Texture2D& TestTexture2D::getTexture (void)
1050 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const
1052 DE_ASSERT(!isCompressed());
1054 de::MovePtr<TestTexture> texture (new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight()));
1056 copyToTexture(*texture);
1061 // TestTexture2DArray
1063 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1064 : TestTexture (format, width, height, arraySize)
1065 , m_texture (format, width, height, arraySize)
1067 allocateLevels(m_texture);
1068 TestTexture::populateLevels(getLevelsVector(m_texture));
1071 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1072 : TestTexture (format, width, height, arraySize)
1073 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize)
1075 allocateLevels(m_texture);
1077 std::vector<tcu::PixelBufferAccess> layers;
1078 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1079 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1080 layers.push_back(getLevel(levelNdx, layerNdx));
1082 TestTexture::populateCompressedLevels(format, layers);
1085 TestTexture2DArray::~TestTexture2DArray (void)
1089 int TestTexture2DArray::getNumLevels (void) const
1091 return m_texture.getNumLevels();
1094 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1096 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1097 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1098 const deUint32 layerOffset = layerSize * layer;
1100 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1103 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1105 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1106 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1107 const deUint32 layerOffset = layerSize * layer;
1109 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1112 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1117 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1122 int TestTexture2DArray::getArraySize (void) const
1124 return m_texture.getNumLayers();
1127 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const
1129 DE_ASSERT(!isCompressed());
1131 de::MovePtr<TestTexture> texture (new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize()));
1133 copyToTexture(*texture);
1140 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1141 : TestTexture (format, width, height, depth)
1142 , m_texture (format, width, height, depth)
1144 allocateLevels(m_texture);
1145 TestTexture::populateLevels(getLevelsVector(m_texture));
1148 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1149 : TestTexture (format, width, height, depth)
1150 , m_texture (tcu::getUncompressedFormat(format), width, height, depth)
1152 allocateLevels(m_texture);
1153 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1156 TestTexture3D::~TestTexture3D (void)
1160 int TestTexture3D::getNumLevels (void) const
1162 return m_texture.getNumLevels();
1165 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1167 DE_ASSERT(layer == 0);
1169 return m_texture.getLevel(level);
1172 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1174 DE_ASSERT(layer == 0);
1176 return m_texture.getLevel(level);
1179 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1184 tcu::Texture3D& TestTexture3D::getTexture (void)
1189 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const
1191 DE_ASSERT(!isCompressed());
1193 de::MovePtr<TestTexture> texture (new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth()));
1195 copyToTexture(*texture);
1202 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1204 tcu::CUBEFACE_POSITIVE_X,
1205 tcu::CUBEFACE_NEGATIVE_X,
1206 tcu::CUBEFACE_POSITIVE_Y,
1207 tcu::CUBEFACE_NEGATIVE_Y,
1208 tcu::CUBEFACE_POSITIVE_Z,
1209 tcu::CUBEFACE_NEGATIVE_Z
1212 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1213 : TestTexture (format, size, size, 1)
1214 , m_texture (format, size)
1216 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1218 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1220 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1221 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1226 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1227 : TestTexture (format, size, size, 1)
1228 , m_texture (tcu::getUncompressedFormat(format), size)
1230 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1232 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1234 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1236 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1237 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1241 TestTexture::populateCompressedLevels(format, levels);
1244 TestTextureCube::~TestTextureCube (void)
1248 int TestTextureCube::getNumLevels (void) const
1250 return m_texture.getNumLevels();
1253 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1255 return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1258 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1260 return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1263 int TestTextureCube::getArraySize (void) const
1265 return (int)tcu::CUBEFACE_LAST;
1268 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1273 tcu::TextureCube& TestTextureCube::getTexture (void)
1278 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const
1280 DE_ASSERT(!isCompressed());
1282 de::MovePtr<TestTexture> texture (new TestTextureCube(format, m_texture.getSize()));
1284 copyToTexture(*texture);
1289 // TestTextureCubeArray
1291 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1292 : TestTexture (format, size, size, arraySize)
1293 , m_texture (format, size, arraySize)
1295 allocateLevels(m_texture);
1296 TestTexture::populateLevels(getLevelsVector(m_texture));
1299 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1300 : TestTexture (format, size, size, arraySize)
1301 , m_texture (tcu::getUncompressedFormat(format), size, arraySize)
1303 DE_ASSERT(arraySize % 6 == 0);
1305 allocateLevels(m_texture);
1307 std::vector<tcu::PixelBufferAccess> layers;
1308 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1309 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1310 layers.push_back(getLevel(levelNdx, layerNdx));
1312 TestTexture::populateCompressedLevels(format, layers);
1315 TestTextureCubeArray::~TestTextureCubeArray (void)
1319 int TestTextureCubeArray::getNumLevels (void) const
1321 return m_texture.getNumLevels();
1324 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1326 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1327 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1328 const deUint32 layerOffset = layerSize * layer;
1330 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1333 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1335 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1336 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1337 const deUint32 layerOffset = layerSize * layer;
1339 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1342 int TestTextureCubeArray::getArraySize (void) const
1344 return m_texture.getDepth();
1347 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1352 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)
1357 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const
1359 DE_ASSERT(!isCompressed());
1361 de::MovePtr<TestTexture> texture (new TestTextureCubeArray(format, m_texture.getSize(), getArraySize()));
1363 copyToTexture(*texture);