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 void getLookupScaleBias (vk::VkFormat format, tcu::Vec4& lookupScale, tcu::Vec4& lookupBias)
169 if (!isCompressedFormat(format))
171 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(mapVkFormat(format));
173 // Needed to normalize various formats to 0..1 range for writing into RT
174 lookupScale = fmtInfo.lookupScale;
175 lookupBias = fmtInfo.lookupBias;
181 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
182 lookupScale = tcu::Vec4(0.5f, 1.0f, 1.0f, 1.0f);
183 lookupBias = tcu::Vec4(0.5f, 0.0f, 0.0f, 0.0f);
186 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
187 lookupScale = tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f);
188 lookupBias = tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f);
192 // else: All supported compressed formats are fine with no normalization.
193 // ASTC LDR blocks decompress to f16 so querying normalization parameters
194 // based on uncompressed formats would actually lead to massive precision loss
195 // and complete lack of coverage in case of R8G8B8A8_UNORM RT.
196 lookupScale = tcu::Vec4(1.0f);
197 lookupBias = tcu::Vec4(0.0f);
203 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface& vk,
206 deUint32 queueFamilyIndex,
207 vk::Allocator& allocator,
210 const tcu::UVec2& renderSize)
212 Move<VkBuffer> buffer;
213 de::MovePtr<Allocation> bufferAlloc;
214 Move<VkCommandPool> cmdPool;
215 Move<VkCommandBuffer> cmdBuffer;
217 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
218 const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
219 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
221 // Create destination buffer
223 const VkBufferCreateInfo bufferParams =
225 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
226 DE_NULL, // const void* pNext;
227 0u, // VkBufferCreateFlags flags;
228 pixelDataSize, // VkDeviceSize size;
229 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
230 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
231 0u, // deUint32 queueFamilyIndexCount;
232 DE_NULL // const deUint32* pQueueFamilyIndices;
235 buffer = createBuffer(vk, device, &bufferParams);
236 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
237 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
240 // Create command pool and buffer
242 const VkCommandPoolCreateInfo cmdPoolParams =
244 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
245 DE_NULL, // const void* pNext;
246 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
247 queueFamilyIndex, // deUint32 queueFamilyIndex;
250 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
252 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
254 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
255 DE_NULL, // const void* pNext;
256 *cmdPool, // VkCommandPool commandPool;
257 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
258 1u // deUint32 bufferCount;
261 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
266 const VkFenceCreateInfo fenceParams =
268 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
269 DE_NULL, // const void* pNext;
270 0u // VkFenceCreateFlags flags;
273 fence = createFence(vk, device, &fenceParams);
276 // Barriers for copying image to buffer
278 const VkImageMemoryBarrier imageBarrier =
280 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
281 DE_NULL, // const void* pNext;
282 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
283 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
284 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
285 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
286 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
287 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
288 image, // VkImage image;
289 { // VkImageSubresourceRange subresourceRange;
290 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
291 0u, // deUint32 baseMipLevel;
292 1u, // deUint32 mipLevels;
293 0u, // deUint32 baseArraySlice;
294 1u // deUint32 arraySize;
298 const VkBufferMemoryBarrier bufferBarrier =
300 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
301 DE_NULL, // const void* pNext;
302 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
303 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
304 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
305 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
306 *buffer, // VkBuffer buffer;
307 0u, // VkDeviceSize offset;
308 pixelDataSize // VkDeviceSize size;
311 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
313 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
314 DE_NULL, // const void* pNext;
315 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
316 (const VkCommandBufferInheritanceInfo*)DE_NULL,
319 // Copy image to buffer
321 const VkBufferImageCopy copyRegion =
323 0u, // VkDeviceSize bufferOffset;
324 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
325 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
326 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource;
327 { 0, 0, 0 }, // VkOffset3D imageOffset;
328 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
331 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
332 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
333 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
334 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
335 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
337 const VkSubmitInfo submitInfo =
339 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
340 DE_NULL, // const void* pNext;
341 0u, // deUint32 waitSemaphoreCount;
342 DE_NULL, // const VkSemaphore* pWaitSemaphores;
344 1u, // deUint32 commandBufferCount;
345 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
346 0u, // deUint32 signalSemaphoreCount;
347 DE_NULL // const VkSemaphore* pSignalSemaphores;
350 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
351 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
354 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
355 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
363 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat)
365 VkImageAspectFlags imageAspectFlags = 0;
367 if (tcu::hasDepthComponent(textureFormat.order))
368 imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
370 if (tcu::hasStencilComponent(textureFormat.order))
371 imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
373 if (imageAspectFlags == 0)
374 imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
376 return imageAspectFlags;
381 void uploadTestTexture (const DeviceInterface& vk,
384 deUint32 queueFamilyIndex,
385 Allocator& allocator,
386 const TestTexture& srcTexture,
390 Move<VkBuffer> buffer;
391 de::MovePtr<Allocation> bufferAlloc;
392 Move<VkCommandPool> cmdPool;
393 Move<VkCommandBuffer> cmdBuffer;
395 const VkImageAspectFlags imageAspectFlags = getImageAspectFlags(srcTexture.getTextureFormat());
397 // Calculate buffer size
398 bufferSize = (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
400 // Create source buffer
402 const VkBufferCreateInfo bufferParams =
404 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
405 DE_NULL, // const void* pNext;
406 0u, // VkBufferCreateFlags flags;
407 bufferSize, // VkDeviceSize size;
408 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
409 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
410 0u, // deUint32 queueFamilyIndexCount;
411 DE_NULL, // const deUint32* pQueueFamilyIndices;
414 buffer = createBuffer(vk, device, &bufferParams);
415 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
416 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
419 // Create command pool and buffer
421 const VkCommandPoolCreateInfo cmdPoolParams =
423 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
424 DE_NULL, // const void* pNext;
425 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
426 queueFamilyIndex, // deUint32 queueFamilyIndex;
429 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
431 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
433 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
434 DE_NULL, // const void* pNext;
435 *cmdPool, // VkCommandPool commandPool;
436 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
437 1u, // deUint32 bufferCount;
440 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
445 const VkFenceCreateInfo fenceParams =
447 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
448 DE_NULL, // const void* pNext;
449 0u // VkFenceCreateFlags flags;
452 fence = createFence(vk, device, &fenceParams);
455 // Barriers for copying buffer to image
456 const VkBufferMemoryBarrier preBufferBarrier =
458 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
459 DE_NULL, // const void* pNext;
460 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
461 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
462 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
463 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
464 *buffer, // VkBuffer buffer;
465 0u, // VkDeviceSize offset;
466 bufferSize // VkDeviceSize size;
469 const VkImageMemoryBarrier preImageBarrier =
471 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
472 DE_NULL, // const void* pNext;
473 0u, // VkAccessFlags srcAccessMask;
474 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
475 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
476 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
477 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
478 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
479 destImage, // VkImage image;
480 { // VkImageSubresourceRange subresourceRange;
481 imageAspectFlags, // VkImageAspectFlags aspectMask;
482 0u, // deUint32 baseMipLevel;
483 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
484 0u, // deUint32 baseArraySlice;
485 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
489 const VkImageMemoryBarrier postImageBarrier =
491 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
492 DE_NULL, // const void* pNext;
493 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
494 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
495 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
496 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout newLayout;
497 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
498 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
499 destImage, // VkImage image;
500 { // VkImageSubresourceRange subresourceRange;
501 imageAspectFlags, // VkImageAspectFlags aspectMask;
502 0u, // deUint32 baseMipLevel;
503 (deUint32)srcTexture.getNumLevels(), // deUint32 mipLevels;
504 0u, // deUint32 baseArraySlice;
505 (deUint32)srcTexture.getArraySize(), // deUint32 arraySize;
509 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
511 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
512 DE_NULL, // const void* pNext;
513 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
514 (const VkCommandBufferInheritanceInfo*)DE_NULL,
517 const std::vector<VkBufferImageCopy> copyRegions = srcTexture.getBufferCopyRegions();
520 srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
521 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
523 // Copy buffer to image
524 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
525 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
526 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
527 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);
529 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
531 const VkSubmitInfo submitInfo =
533 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
534 DE_NULL, // const void* pNext;
535 0u, // deUint32 waitSemaphoreCount;
536 DE_NULL, // const VkSemaphore* pWaitSemaphores;
538 1u, // deUint32 commandBufferCount;
539 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
540 0u, // deUint32 signalSemaphoreCount;
541 DE_NULL // const VkSemaphore* pSignalSemaphores;
544 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
545 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
548 // Utilities for test textures
550 template<typename TcuTextureType>
551 void allocateLevels (TcuTextureType& texture)
553 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
554 texture.allocLevel(levelNdx);
557 template<typename TcuTextureType>
558 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
560 std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
562 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
563 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
570 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
572 DE_ASSERT(width >= 1);
573 DE_ASSERT(height >= 1);
574 DE_ASSERT(depth >= 1);
582 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
584 DE_ASSERT(width >= 1);
585 DE_ASSERT(height >= 1);
586 DE_ASSERT(depth >= 1);
594 TestTexture::~TestTexture (void)
596 for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
597 delete m_compressedLevels[levelNdx];
600 deUint32 TestTexture::getSize (void) const
602 std::vector<deUint32> offsetMultiples;
603 deUint32 textureSize = 0;
605 offsetMultiples.push_back(4);
606 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
608 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
610 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
612 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
613 textureSize = getNextMultiple(offsetMultiples, textureSize);
614 textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
621 deUint32 TestTexture::getCompressedSize (void) const
624 throw tcu::InternalError("Texture is not compressed");
626 std::vector<deUint32> offsetMultiples;
627 deUint32 textureSize = 0;
629 offsetMultiples.push_back(4);
630 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
632 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
634 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
636 textureSize = getNextMultiple(offsetMultiples, textureSize);
637 textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
644 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
646 DE_ASSERT(level >= 0 && level < getNumLevels());
647 DE_ASSERT(layer >= 0 && layer < getArraySize());
649 return *m_compressedLevels[level * getArraySize() + layer];
652 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
654 DE_ASSERT(level >= 0 && level < getNumLevels());
655 DE_ASSERT(layer >= 0 && layer < getArraySize());
657 return *m_compressedLevels[level * getArraySize() + layer];
660 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
662 std::vector<deUint32> offsetMultiples;
663 std::vector<VkBufferImageCopy> regions;
664 deUint32 layerDataOffset = 0;
666 offsetMultiples.push_back(4);
670 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
672 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
674 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
676 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
677 tcu::IVec3 blockPixelSize = getBlockPixelSize(level.getFormat());
678 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
680 const VkBufferImageCopy layerRegion =
682 layerDataOffset, // VkDeviceSize bufferOffset;
683 (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()), // deUint32 bufferRowLength;
684 (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()), // deUint32 bufferImageHeight;
685 { // VkImageSubresourceLayers imageSubresource;
686 VK_IMAGE_ASPECT_COLOR_BIT,
691 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
692 { // VkExtent3D imageExtent;
693 (deUint32)level.getWidth(),
694 (deUint32)level.getHeight(),
695 (deUint32)level.getDepth()
699 regions.push_back(layerRegion);
700 layerDataOffset += level.getDataSize();
706 std::vector<VkImageAspectFlags> imageAspects;
707 tcu::TextureFormat textureFormat = getTextureFormat();
709 if (tcu::hasDepthComponent(textureFormat.order))
710 imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
712 if (tcu::hasStencilComponent(textureFormat.order))
713 imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
715 if (imageAspects.empty())
716 imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
718 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
720 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
722 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
724 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
726 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
728 for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
730 const VkBufferImageCopy layerRegion =
732 layerDataOffset, // VkDeviceSize bufferOffset;
733 (deUint32)level.getWidth(), // deUint32 bufferRowLength;
734 (deUint32)level.getHeight(), // deUint32 bufferImageHeight;
735 { // VkImageSubresourceLayers imageSubresource;
736 imageAspects[aspectIndex],
741 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
742 { // VkExtent3D imageExtent;
743 (deUint32)level.getWidth(),
744 (deUint32)level.getHeight(),
745 (deUint32)level.getDepth()
749 regions.push_back(layerRegion);
751 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
759 void TestTexture::write (deUint8* destPtr) const
761 std::vector<deUint32> offsetMultiples;
762 deUint32 levelOffset = 0;
764 offsetMultiples.push_back(4);
768 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
770 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
772 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
774 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
776 const tcu::CompressedTexture& compressedTex = getCompressedLevel(levelNdx, layerNdx);
778 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
779 levelOffset += compressedTex.getDataSize();
785 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
787 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
789 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
791 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
793 const tcu::ConstPixelBufferAccess srcAccess = getLevel(levelNdx, layerNdx);
794 const tcu::PixelBufferAccess destAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
796 tcu::copy(destAccess, srcAccess);
797 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
803 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
805 for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
806 TestTexture::fillWithGradient(levels[levelNdx]);
809 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
811 // Generate random compressed data and update decompressed data
813 de::Random random(123);
815 for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
817 const tcu::PixelBufferAccess level = decompressedLevels[levelNdx];
818 tcu::CompressedTexture* compressedLevel = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
819 deUint8* const compressedData = (deUint8*)compressedLevel->getData();
821 if (tcu::isAstcFormat(format))
823 // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
824 tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
825 format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
829 // Generate random compressed data
830 // Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
831 if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
832 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
833 compressedData[byteNdx] = 0xFF & random.getUint32();
836 m_compressedLevels.push_back(compressedLevel);
838 // Store decompressed data
839 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
843 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
845 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
846 tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
851 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
852 : TestTexture (format, width, 1, 1)
853 , m_texture (format, width)
855 allocateLevels(m_texture);
856 TestTexture::populateLevels(getLevelsVector(m_texture));
859 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
860 : TestTexture (format, width, 1, 1)
861 , m_texture (tcu::getUncompressedFormat(format), width)
863 allocateLevels(m_texture);
864 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
867 TestTexture1D::~TestTexture1D (void)
871 int TestTexture1D::getNumLevels (void) const
873 return m_texture.getNumLevels();
876 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
878 DE_ASSERT(layer == 0);
880 return m_texture.getLevel(level);
883 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
885 DE_ASSERT(layer == 0);
887 return m_texture.getLevel(level);
890 const tcu::Texture1D& TestTexture1D::getTexture (void) const
895 tcu::Texture1D& TestTexture1D::getTexture (void)
900 // TestTexture1DArray
902 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
903 : TestTexture (format, width, 1, arraySize)
904 , m_texture (format, width, arraySize)
906 allocateLevels(m_texture);
907 TestTexture::populateLevels(getLevelsVector(m_texture));
910 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
911 : TestTexture (format, width, 1, arraySize)
912 , m_texture (tcu::getUncompressedFormat(format), width, arraySize)
914 allocateLevels(m_texture);
916 std::vector<tcu::PixelBufferAccess> layers;
917 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
918 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
919 layers.push_back(getLevel(levelNdx, layerNdx));
921 TestTexture::populateCompressedLevels(format, layers);
924 TestTexture1DArray::~TestTexture1DArray (void)
928 int TestTexture1DArray::getNumLevels (void) const
930 return m_texture.getNumLevels();
933 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
935 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
936 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
937 const deUint32 layerOffset = layerSize * layer;
939 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
942 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
944 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
945 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
946 const deUint32 layerOffset = layerSize * layer;
948 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
951 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
956 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
961 int TestTexture1DArray::getArraySize (void) const
963 return m_texture.getNumLayers();
968 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
969 : TestTexture (format, width, height, 1)
970 , m_texture (format, width, height)
972 allocateLevels(m_texture);
973 TestTexture::populateLevels(getLevelsVector(m_texture));
976 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
977 : TestTexture (format, width, height, 1)
978 , m_texture (tcu::getUncompressedFormat(format), width, height)
980 allocateLevels(m_texture);
981 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
984 TestTexture2D::~TestTexture2D (void)
988 int TestTexture2D::getNumLevels (void) const
990 return m_texture.getNumLevels();
993 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
995 DE_ASSERT(layer == 0);
997 return m_texture.getLevel(level);
1000 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1002 DE_ASSERT(layer == 0);
1004 return m_texture.getLevel(level);
1007 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1012 tcu::Texture2D& TestTexture2D::getTexture (void)
1017 // TestTexture2DArray
1019 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1020 : TestTexture (format, width, height, arraySize)
1021 , m_texture (format, width, height, arraySize)
1023 allocateLevels(m_texture);
1024 TestTexture::populateLevels(getLevelsVector(m_texture));
1027 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1028 : TestTexture (format, width, height, arraySize)
1029 , m_texture (tcu::getUncompressedFormat(format), width, height, arraySize)
1031 allocateLevels(m_texture);
1033 std::vector<tcu::PixelBufferAccess> layers;
1034 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1035 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1036 layers.push_back(getLevel(levelNdx, layerNdx));
1038 TestTexture::populateCompressedLevels(format, layers);
1041 TestTexture2DArray::~TestTexture2DArray (void)
1045 int TestTexture2DArray::getNumLevels (void) const
1047 return m_texture.getNumLevels();
1050 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1052 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1053 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1054 const deUint32 layerOffset = layerSize * layer;
1056 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1059 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1061 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1062 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1063 const deUint32 layerOffset = layerSize * layer;
1065 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1068 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1073 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1078 int TestTexture2DArray::getArraySize (void) const
1080 return m_texture.getNumLayers();
1086 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1087 : TestTexture (format, width, height, depth)
1088 , m_texture (format, width, height, depth)
1090 allocateLevels(m_texture);
1091 TestTexture::populateLevels(getLevelsVector(m_texture));
1094 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1095 : TestTexture (format, width, height, depth)
1096 , m_texture (tcu::getUncompressedFormat(format), width, height, depth)
1098 allocateLevels(m_texture);
1099 TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1102 TestTexture3D::~TestTexture3D (void)
1106 int TestTexture3D::getNumLevels (void) const
1108 return m_texture.getNumLevels();
1111 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1113 DE_ASSERT(layer == 0);
1115 return m_texture.getLevel(level);
1118 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1120 DE_ASSERT(layer == 0);
1122 return m_texture.getLevel(level);
1125 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1130 tcu::Texture3D& TestTexture3D::getTexture (void)
1137 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1139 tcu::CUBEFACE_POSITIVE_X,
1140 tcu::CUBEFACE_NEGATIVE_X,
1141 tcu::CUBEFACE_POSITIVE_Y,
1142 tcu::CUBEFACE_NEGATIVE_Y,
1143 tcu::CUBEFACE_POSITIVE_Z,
1144 tcu::CUBEFACE_NEGATIVE_Z
1147 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1148 : TestTexture (format, size, size, 1)
1149 , m_texture (format, size)
1151 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1153 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1155 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1156 TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1161 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1162 : TestTexture (format, size, size, 1)
1163 , m_texture (tcu::getUncompressedFormat(format), size)
1165 std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1167 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1169 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1171 m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1172 levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1176 TestTexture::populateCompressedLevels(format, levels);
1179 TestTextureCube::~TestTextureCube (void)
1183 int TestTextureCube::getNumLevels (void) const
1185 return m_texture.getNumLevels();
1188 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1190 return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1193 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1195 return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1198 int TestTextureCube::getArraySize (void) const
1200 return (int)tcu::CUBEFACE_LAST;
1203 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1208 tcu::TextureCube& TestTextureCube::getTexture (void)
1213 // TestTextureCubeArray
1215 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1216 : TestTexture (format, size, size, arraySize)
1217 , m_texture (format, size, arraySize)
1219 allocateLevels(m_texture);
1220 TestTexture::populateLevels(getLevelsVector(m_texture));
1223 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1224 : TestTexture (format, size, size, arraySize)
1225 , m_texture (tcu::getUncompressedFormat(format), size, arraySize)
1227 DE_ASSERT(arraySize % 6 == 0);
1229 allocateLevels(m_texture);
1231 std::vector<tcu::PixelBufferAccess> layers;
1232 for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1233 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1234 layers.push_back(getLevel(levelNdx, layerNdx));
1236 TestTexture::populateCompressedLevels(format, layers);
1239 TestTextureCubeArray::~TestTextureCubeArray (void)
1243 int TestTextureCubeArray::getNumLevels (void) const
1245 return m_texture.getNumLevels();
1248 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1250 const tcu::PixelBufferAccess levelLayers = m_texture.getLevel(level);
1251 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1252 const deUint32 layerOffset = layerSize * layer;
1254 return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1257 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1259 const tcu::ConstPixelBufferAccess levelLayers = m_texture.getLevel(level);
1260 const deUint32 layerSize = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1261 const deUint32 layerOffset = layerSize * layer;
1263 return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1266 int TestTextureCubeArray::getArraySize (void) const
1268 return m_texture.getDepth();
1271 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1276 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)