Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineImageUtil.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  *
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:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
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.
22  *
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.
30  *
31  *//*!
32  * \file
33  * \brief Utilities for images.
34  *//*--------------------------------------------------------------------*/
35
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"
43
44 namespace vkt
45 {
46 namespace pipeline
47 {
48
49 using namespace vk;
50
51 /*! Gets the next multiple of a given divisor */
52 static deUint32 getNextMultiple (deUint32 divisor, deUint32 value)
53 {
54         if (value % divisor == 0)
55         {
56                 return value;
57         }
58         return value + divisor - (value % divisor);
59 }
60
61 /*! Gets the next value that is multiple of all given divisors */
62 static deUint32 getNextMultiple (const std::vector<deUint32>& divisors, deUint32 value)
63 {
64         deUint32        nextMultiple            = value;
65         bool            nextMultipleFound       = false;
66
67         while (true)
68         {
69                 nextMultipleFound = true;
70
71                 for (size_t divNdx = 0; divNdx < divisors.size(); divNdx++)
72                         nextMultipleFound = nextMultipleFound && (nextMultiple % divisors[divNdx] == 0);
73
74                 if (nextMultipleFound)
75                         break;
76
77                 DE_ASSERT(nextMultiple < ~((deUint32)0u));
78                 nextMultiple = getNextMultiple(divisors[0], nextMultiple + 1);
79         }
80
81         return nextMultiple;
82 }
83
84 bool isSupportedSamplableFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
85 {
86         if (isCompressedFormat(format))
87         {
88                 VkPhysicalDeviceFeatures                physicalFeatures;
89                 const tcu::CompressedTexFormat  compressedFormat        = mapVkCompressedFormat(format);
90
91                 instanceInterface.getPhysicalDeviceFeatures(device, &physicalFeatures);
92
93                 if (tcu::isAstcFormat(compressedFormat))
94                 {
95                         if (!physicalFeatures.textureCompressionASTC_LDR)
96                                 return false;
97                 }
98                 else if (tcu::isEtcFormat(compressedFormat))
99                 {
100                         if (!physicalFeatures.textureCompressionETC2)
101                                 return false;
102                 }
103                 else
104                 {
105                         DE_FATAL("Unsupported compressed format");
106                 }
107         }
108
109         VkFormatProperties      formatProps;
110         instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
111
112         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u;
113 }
114
115 VkBorderColor getFormatBorderColor (BorderColor color, VkFormat format)
116 {
117         if (!isCompressedFormat(format) && (isIntFormat(format) || isUintFormat(format)))
118         {
119                 switch (color)
120                 {
121                         case BORDER_COLOR_OPAQUE_BLACK:                 return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
122                         case BORDER_COLOR_OPAQUE_WHITE:                 return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
123                         case BORDER_COLOR_TRANSPARENT_BLACK:    return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
124                         default:
125                                 break;
126                 }
127         }
128         else
129         {
130                 switch (color)
131                 {
132                         case BORDER_COLOR_OPAQUE_BLACK:                 return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
133                         case BORDER_COLOR_OPAQUE_WHITE:                 return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
134                         case BORDER_COLOR_TRANSPARENT_BLACK:    return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
135                         default:
136                                 break;
137                 }
138         }
139
140         DE_ASSERT(false);
141         return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
142 }
143
144 de::MovePtr<tcu::TextureLevel> readColorAttachment (const vk::DeviceInterface&  vk,
145                                                                                                         vk::VkDevice                            device,
146                                                                                                         vk::VkQueue                                     queue,
147                                                                                                         deUint32                                        queueFamilyIndex,
148                                                                                                         vk::Allocator&                          allocator,
149                                                                                                         vk::VkImage                                     image,
150                                                                                                         vk::VkFormat                            format,
151                                                                                                         const tcu::UVec2&                       renderSize)
152 {
153         Move<VkBuffer>                                  buffer;
154         de::MovePtr<Allocation>                 bufferAlloc;
155         Move<VkCommandPool>                             cmdPool;
156         Move<VkCommandBuffer>                   cmdBuffer;
157         Move<VkFence>                                   fence;
158         const tcu::TextureFormat                tcuFormat               = mapVkFormat(format);
159         const VkDeviceSize                              pixelDataSize   = renderSize.x() * renderSize.y() * tcuFormat.getPixelSize();
160         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(tcuFormat, renderSize.x(), renderSize.y()));
161
162         // Create destination buffer
163         {
164                 const VkBufferCreateInfo bufferParams =
165                 {
166                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
167                         DE_NULL,                                                                        // const void*                  pNext;
168                         0u,                                                                                     // VkBufferCreateFlags  flags;
169                         pixelDataSize,                                                          // VkDeviceSize                 size;
170                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
171                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
172                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
173                         DE_NULL                                                                         // const deUint32*              pQueueFamilyIndices;
174                 };
175
176                 buffer          = createBuffer(vk, device, &bufferParams);
177                 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
178                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
179         }
180
181         // Create command pool and buffer
182         {
183                 const VkCommandPoolCreateInfo cmdPoolParams =
184                 {
185                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
186                         DE_NULL,                                                                                // const void*                  pNext;
187                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
188                         queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
189                 };
190
191                 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
192
193                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
194                 {
195                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
196                         DE_NULL,                                                                                // const void*                          pNext;
197                         *cmdPool,                                                                               // VkCommandPool                        commandPool;
198                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
199                         1u                                                                                              // deUint32                                     bufferCount;
200                 };
201
202                 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
203         }
204
205         // Create fence
206         {
207                 const VkFenceCreateInfo fenceParams =
208                 {
209                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
210                         DE_NULL,                                                                        // const void*                  pNext;
211                         0u                                                                                      // VkFenceCreateFlags   flags;
212                 };
213
214                 fence = createFence(vk, device, &fenceParams);
215         }
216
217         // Barriers for copying image to buffer
218
219         const VkImageMemoryBarrier imageBarrier =
220         {
221                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
222                 DE_NULL,                                                                        // const void*                          pNext;
223                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
224                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
225                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
226                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
227                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
228                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
229                 image,                                                                          // VkImage                                      image;
230                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
231                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
232                         0u,                                                     // deUint32                             baseMipLevel;
233                         1u,                                                     // deUint32                             mipLevels;
234                         0u,                                                     // deUint32                             baseArraySlice;
235                         1u                                                      // deUint32                             arraySize;
236                 }
237         };
238
239         const VkBufferMemoryBarrier bufferBarrier =
240         {
241                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
242                 DE_NULL,                                                                        // const void*          pNext;
243                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
244                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
245                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
246                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
247                 *buffer,                                                                        // VkBuffer                     buffer;
248                 0u,                                                                                     // VkDeviceSize         offset;
249                 pixelDataSize                                                           // VkDeviceSize         size;
250         };
251
252         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
253         {
254                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
255                 DE_NULL,                                                                                                // const void*                                          pNext;
256                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
257                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
258         };
259
260         // Copy image to buffer
261
262         const VkBufferImageCopy copyRegion =
263         {
264                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
265                 (deUint32)renderSize.x(),                                               // deUint32                                     bufferRowLength;
266                 (deUint32)renderSize.y(),                                               // deUint32                                     bufferImageHeight;
267                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u },              // VkImageSubresourceLayers     imageSubresource;
268                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
269                 { renderSize.x(), renderSize.y(), 1u }                  // VkExtent3D                           imageExtent;
270         };
271
272         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
273         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
274         vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, &copyRegion);
275         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
276         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
277
278         const VkSubmitInfo submitInfo =
279         {
280                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
281                 DE_NULL,                                                // const void*                          pNext;
282                 0u,                                                             // deUint32                                     waitSemaphoreCount;
283                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
284                 DE_NULL,
285                 1u,                                                             // deUint32                                     commandBufferCount;
286                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
287                 0u,                                                             // deUint32                                     signalSemaphoreCount;
288                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
289         };
290
291         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
292         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
293
294         // Read buffer data
295         invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
296         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
297
298         return resultLevel;
299 }
300
301 void uploadTestTexture (const DeviceInterface&                  vk,
302                                                 VkDevice                                                device,
303                                                 VkQueue                                                 queue,
304                                                 deUint32                                                queueFamilyIndex,
305                                                 Allocator&                                              allocator,
306                                                 const TestTexture&                              srcTexture,
307                                                 VkImage                                                 destImage)
308 {
309         deUint32                                                bufferSize;
310         Move<VkBuffer>                                  buffer;
311         de::MovePtr<Allocation>                 bufferAlloc;
312         Move<VkCommandPool>                             cmdPool;
313         Move<VkCommandBuffer>                   cmdBuffer;
314         Move<VkFence>                                   fence;
315         std::vector<deUint32>                   levelDataSizes;
316
317         // Calculate buffer size
318         bufferSize =  (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
319
320         // Create source buffer
321         {
322                 const VkBufferCreateInfo bufferParams =
323                 {
324                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
325                         DE_NULL,                                                                        // const void*                  pNext;
326                         0u,                                                                                     // VkBufferCreateFlags  flags;
327                         bufferSize,                                                                     // VkDeviceSize                 size;
328                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
329                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
330                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
331                         DE_NULL,                                                                        // const deUint32*              pQueueFamilyIndices;
332                 };
333
334                 buffer          = createBuffer(vk, device, &bufferParams);
335                 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
336                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
337         }
338
339         // Create command pool and buffer
340         {
341                 const VkCommandPoolCreateInfo cmdPoolParams =
342                 {
343                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                      sType;
344                         DE_NULL,                                                                                // const void*                          pNext;
345                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
346                         queueFamilyIndex,                                                               // deUint32                                     queueFamilyIndex;
347                 };
348
349                 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
350
351                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
352                 {
353                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
354                         DE_NULL,                                                                                // const void*                          pNext;
355                         *cmdPool,                                                                               // VkCommandPool                        commandPool;
356                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
357                         1u,                                                                                             // deUint32                                     bufferCount;
358                 };
359
360                 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
361         }
362
363         // Create fence
364         {
365                 const VkFenceCreateInfo fenceParams =
366                 {
367                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
368                         DE_NULL,                                                                        // const void*                  pNext;
369                         0u                                                                                      // VkFenceCreateFlags   flags;
370                 };
371
372                 fence = createFence(vk, device, &fenceParams);
373         }
374
375         // Barriers for copying buffer to image
376         const VkBufferMemoryBarrier preBufferBarrier =
377         {
378                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
379                 DE_NULL,                                                                        // const void*          pNext;
380                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
381                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
382                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
383                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
384                 *buffer,                                                                        // VkBuffer                     buffer;
385                 0u,                                                                                     // VkDeviceSize         offset;
386                 bufferSize                                                                      // VkDeviceSize         size;
387         };
388
389         const VkImageMemoryBarrier preImageBarrier =
390         {
391                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
392                 DE_NULL,                                                                                // const void*                          pNext;
393                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
394                 0u,                                                                                             // VkAccessFlags                        dstAccessMask;
395                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
396                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
397                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
398                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
399                 destImage,                                                                              // VkImage                                      image;
400                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
401                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspect        aspect;
402                         0u,                                                                             // deUint32                     baseMipLevel;
403                         (deUint32)srcTexture.getNumLevels(),    // deUint32                     mipLevels;
404                         0u,                                                                             // deUint32                     baseArraySlice;
405                         (deUint32)srcTexture.getArraySize(),    // deUint32                     arraySize;
406                 }
407         };
408
409         const VkImageMemoryBarrier postImageBarrier =
410         {
411                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
412                 DE_NULL,                                                                                // const void*                          pNext;
413                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
414                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
415                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
416                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,               // VkImageLayout                        newLayout;
417                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
418                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
419                 destImage,                                                                              // VkImage                                      image;
420                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
421                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspect        aspect;
422                         0u,                                                                             // deUint32                     baseMipLevel;
423                         (deUint32)srcTexture.getNumLevels(),    // deUint32                     mipLevels;
424                         0u,                                                                             // deUint32                     baseArraySlice;
425                         (deUint32)srcTexture.getArraySize(),    // deUint32                     arraySize;
426                 }
427         };
428
429         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
430         {
431                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
432                 DE_NULL,                                                                                // const void*                                          pNext;
433                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
434                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
435         };
436
437         const std::vector<VkBufferImageCopy>    copyRegions             = srcTexture.getBufferCopyRegions();
438
439         // Write buffer data
440         srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
441         flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
442
443         // Copy buffer to image
444         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
445         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
446         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
447         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
448
449         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
450
451         const VkSubmitInfo submitInfo =
452         {
453                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
454                 DE_NULL,                                                // const void*                          pNext;
455                 0u,                                                             // deUint32                                     waitSemaphoreCount;
456                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
457                 DE_NULL,
458                 1u,                                                             // deUint32                                     commandBufferCount;
459                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
460                 0u,                                                             // deUint32                                     signalSemaphoreCount;
461                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
462         };
463
464         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
465         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
466 }
467
468
469 // Utilities for test textures
470
471 template<typename TcuTextureType>
472 void allocateLevels (TcuTextureType& texture)
473 {
474         for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
475                 texture.allocLevel(levelNdx);
476 }
477
478 template<typename TcuTextureType>
479 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
480 {
481         std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
482
483         for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
484                 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
485
486         return levels;
487 }
488
489
490 // TestTexture
491
492 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
493 {
494         DE_ASSERT(width >= 1);
495         DE_ASSERT(height >= 1);
496         DE_ASSERT(depth >= 1);
497
498         DE_UNREF(format);
499         DE_UNREF(width);
500         DE_UNREF(height);
501         DE_UNREF(depth);
502 }
503
504 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
505 {
506         DE_ASSERT(width >= 1);
507         DE_ASSERT(height >= 1);
508         DE_ASSERT(depth >= 1);
509
510         DE_UNREF(format);
511         DE_UNREF(width);
512         DE_UNREF(height);
513         DE_UNREF(depth);
514 }
515
516 TestTexture::~TestTexture (void)
517 {
518         for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
519                 delete m_compressedLevels[levelNdx];
520 }
521
522 deUint32 TestTexture::getSize (void) const
523 {
524         std::vector<deUint32>   offsetMultiples;
525         deUint32                                textureSize = 0;
526
527         offsetMultiples.push_back(4);
528         offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
529
530         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
531         {
532                 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
533                 {
534                         const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
535                         textureSize = getNextMultiple(offsetMultiples, textureSize);
536                         textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
537                 }
538         }
539
540         return textureSize;
541 }
542
543 deUint32 TestTexture::getCompressedSize (void) const
544 {
545         if (!isCompressed())
546                 throw tcu::InternalError("Texture is not compressed");
547
548         std::vector<deUint32>   offsetMultiples;
549         deUint32                                textureSize                     = 0;
550
551         offsetMultiples.push_back(4);
552         offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
553
554         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
555         {
556                 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
557                 {
558                         textureSize = getNextMultiple(offsetMultiples, textureSize);
559                         textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
560                 }
561         }
562
563         return textureSize;
564 }
565
566 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
567 {
568         DE_ASSERT(level >= 0 && level < getNumLevels());
569         DE_ASSERT(layer >= 0 && layer < getArraySize());
570
571         return *m_compressedLevels[level * getArraySize() + layer];
572 }
573
574 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
575 {
576         DE_ASSERT(level >= 0 && level < getNumLevels());
577         DE_ASSERT(layer >= 0 && layer < getArraySize());
578
579         return *m_compressedLevels[level * getArraySize() + layer];
580 }
581
582 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
583 {
584         std::vector<deUint32>                   offsetMultiples;
585         std::vector<VkBufferImageCopy>  regions;
586         deUint32                                                layerDataOffset = 0;
587
588         offsetMultiples.push_back(4);
589
590         if (isCompressed())
591         {
592                 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
593
594                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
595                 {
596                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
597                         {
598                                 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
599                                 tcu::IVec3 blockPixelSize                       = getBlockPixelSize(level.getFormat());
600                                 layerDataOffset                                         = getNextMultiple(offsetMultiples, layerDataOffset);
601
602                                 const VkBufferImageCopy layerRegion =
603                                 {
604                                         layerDataOffset,                                                                                                        // VkDeviceSize                         bufferOffset;
605                                         (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()),        // deUint32                                     bufferRowLength;
606                                         (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()),       // deUint32                                     bufferImageHeight;
607                                         {                                                                                                                                       // VkImageSubresourceLayers     imageSubresource;
608                                                 VK_IMAGE_ASPECT_COLOR_BIT,
609                                                 (deUint32)levelNdx,
610                                                 (deUint32)layerNdx,
611                                                 1u
612                                         },
613                                         { 0u, 0u, 0u },                                                 // VkOffset3D                           imageOffset;
614                                         {                                                                               // VkExtent3D                           imageExtent;
615                                                 (deUint32)level.getWidth(),
616                                                 (deUint32)level.getHeight(),
617                                                 (deUint32)level.getDepth()
618                                         }
619                                 };
620
621                                 regions.push_back(layerRegion);
622                                 layerDataOffset += level.getDataSize();
623                         }
624                 }
625         }
626         else
627         {
628                 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
629
630                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
631                 {
632                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
633                         {
634                                 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
635
636                                 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
637
638                                 const VkBufferImageCopy layerRegion =
639                                 {
640                                         layerDataOffset,                                                // VkDeviceSize                         bufferOffset;
641                                         (deUint32)level.getWidth(),                             // deUint32                                     bufferRowLength;
642                                         (deUint32)level.getHeight(),                    // deUint32                                     bufferImageHeight;
643                                         {                                                                               // VkImageSubresourceLayers     imageSubresource;
644                                                 VK_IMAGE_ASPECT_COLOR_BIT,
645                                                 (deUint32)levelNdx,
646                                                 (deUint32)layerNdx,
647                                                 1u
648                                         },
649                                         { 0u, 0u, 0u },                                                 // VkOffset3D                   imageOffset;
650                                         {                                                                               // VkExtent3D                   imageExtent;
651                                                 (deUint32)level.getWidth(),
652                                                 (deUint32)level.getHeight(),
653                                                 (deUint32)level.getDepth()
654                                         }
655                                 };
656
657                                 regions.push_back(layerRegion);
658                                 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
659                         }
660                 }
661         }
662
663         return regions;
664 }
665
666 void TestTexture::write (deUint8* destPtr) const
667 {
668         std::vector<deUint32>   offsetMultiples;
669         deUint32                                levelOffset             = 0;
670
671         offsetMultiples.push_back(4);
672
673         if (isCompressed())
674         {
675                 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
676
677                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
678                 {
679                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
680                         {
681                                 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
682
683                                 const tcu::CompressedTexture&           compressedTex   = getCompressedLevel(levelNdx, layerNdx);
684
685                                 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
686                                 levelOffset += compressedTex.getDataSize();
687                         }
688                 }
689         }
690         else
691         {
692                 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
693
694                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
695                 {
696                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
697                         {
698                                 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
699
700                                 const tcu::ConstPixelBufferAccess       srcAccess               = getLevel(levelNdx, layerNdx);
701                                 const tcu::PixelBufferAccess            destAccess              (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
702
703                                 tcu::copy(destAccess, srcAccess);
704                                 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
705                         }
706                 }
707         }
708 }
709
710 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
711 {
712         for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
713                 TestTexture::fillWithGradient(levels[levelNdx]);
714 }
715
716 void TestTexture::populateCompressedLevels (const tcu::CompressedTexFormat& format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
717 {
718         // Generate random compressed data and update decompressed data
719
720         de::Random random(123);
721
722         for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
723         {
724                 const tcu::PixelBufferAccess    level                           = decompressedLevels[levelNdx];
725                 tcu::CompressedTexture*                 compressedLevel         = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
726                 deUint8* const                                  compressedData          = (deUint8*)compressedLevel->getData();
727
728                 // Generate random compressed data
729                 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
730                         compressedData[byteNdx] = 0xFF & random.getUint32();
731
732                 m_compressedLevels.push_back(compressedLevel);
733
734                 // Store decompressed data
735                 compressedLevel->decompress(level, tcu::TexDecompressionParams::ASTCMODE_LDR);
736         }
737 }
738
739 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
740 {
741         const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
742         tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
743 }
744
745 // TestTexture1D
746
747 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
748         : TestTexture   (format, width, 1, 1)
749         , m_texture             (format, width)
750 {
751         allocateLevels(m_texture);
752         TestTexture::populateLevels(getLevelsVector(m_texture));
753 }
754
755 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
756         : TestTexture   (format, width, 1, 1)
757         , m_texture             (tcu::getUncompressedFormat(format), width)
758 {
759         allocateLevels(m_texture);
760         TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
761 }
762
763 TestTexture1D::~TestTexture1D (void)
764 {
765 }
766
767 int TestTexture1D::getNumLevels (void) const
768 {
769         return m_texture.getNumLevels();
770 }
771
772 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
773 {
774         DE_ASSERT(layer == 0);
775         return m_texture.getLevel(level);
776 }
777
778 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
779 {
780         DE_ASSERT(layer == 0);
781         return m_texture.getLevel(level);
782 }
783
784 const tcu::Texture1D& TestTexture1D::getTexture (void) const
785 {
786         return m_texture;
787 }
788
789
790 // TestTexture1DArray
791
792 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
793         : TestTexture   (format, width, 1, arraySize)
794         , m_texture             (format, width, arraySize)
795 {
796         allocateLevels(m_texture);
797         TestTexture::populateLevels(getLevelsVector(m_texture));
798 }
799
800 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
801         : TestTexture   (format, width, 1, arraySize)
802         , m_texture             (tcu::getUncompressedFormat(format), width, arraySize)
803 {
804         allocateLevels(m_texture);
805
806         std::vector<tcu::PixelBufferAccess> layers;
807         for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
808                 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
809                         layers.push_back(getLevel(levelNdx, layerNdx));
810
811         TestTexture::populateCompressedLevels(format, layers);
812 }
813
814 TestTexture1DArray::~TestTexture1DArray (void)
815 {
816 }
817
818 int TestTexture1DArray::getNumLevels (void) const
819 {
820         return m_texture.getNumLevels();
821 }
822
823 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
824 {
825         const tcu::PixelBufferAccess    levelLayers     = m_texture.getLevel(level);
826         const deUint32                                  layerSize       = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
827         const deUint32                                  layerOffset     = layerSize * layer;
828
829         return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
830 }
831
832 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
833 {
834         const tcu::ConstPixelBufferAccess       levelLayers     = m_texture.getLevel(level);
835         const deUint32                                          layerSize       = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
836         const deUint32                                          layerOffset     = layerSize * layer;
837
838         return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
839 }
840
841 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
842 {
843         return m_texture;
844 }
845
846 int TestTexture1DArray::getArraySize (void) const
847 {
848         return m_texture.getNumLayers();
849 }
850
851
852 // TestTexture2D
853
854 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
855         : TestTexture   (format, width, height, 1)
856         , m_texture             (format, width, height)
857 {
858         allocateLevels(m_texture);
859         TestTexture::populateLevels(getLevelsVector(m_texture));
860 }
861
862 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
863         : TestTexture   (format, width, height, 1)
864         , m_texture             (tcu::getUncompressedFormat(format), width, height)
865 {
866         allocateLevels(m_texture);
867         TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
868 }
869
870 TestTexture2D::~TestTexture2D (void)
871 {
872 }
873
874 int TestTexture2D::getNumLevels (void) const
875 {
876         return m_texture.getNumLevels();
877 }
878
879 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
880 {
881         DE_ASSERT(layer == 0);
882         return m_texture.getLevel(level);
883 }
884
885 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
886 {
887         DE_ASSERT(layer == 0);
888         return m_texture.getLevel(level);
889 }
890
891 const tcu::Texture2D& TestTexture2D::getTexture (void) const
892 {
893         return m_texture;
894 }
895
896
897 // TestTexture2DArray
898
899 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
900         : TestTexture   (format, width, height, arraySize)
901         , m_texture             (format, width, height, arraySize)
902 {
903         allocateLevels(m_texture);
904         TestTexture::populateLevels(getLevelsVector(m_texture));
905 }
906
907 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
908         : TestTexture   (format, width, height, arraySize)
909         , m_texture             (tcu::getUncompressedFormat(format), width, height, arraySize)
910 {
911         allocateLevels(m_texture);
912
913         std::vector<tcu::PixelBufferAccess> layers;
914         for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
915                 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
916                         layers.push_back(getLevel(levelNdx, layerNdx));
917
918         TestTexture::populateCompressedLevels(format, layers);
919 }
920
921 TestTexture2DArray::~TestTexture2DArray (void)
922 {
923 }
924
925 int TestTexture2DArray::getNumLevels (void) const
926 {
927         return m_texture.getNumLevels();
928 }
929
930 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
931 {
932         const tcu::PixelBufferAccess    levelLayers     = m_texture.getLevel(level);
933         const deUint32                                  layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
934         const deUint32                                  layerOffset     = layerSize * layer;
935
936         return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
937 }
938
939 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
940 {
941         const tcu::ConstPixelBufferAccess       levelLayers     = m_texture.getLevel(level);
942         const deUint32                                          layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
943         const deUint32                                          layerOffset     = layerSize * layer;
944
945         return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
946 }
947
948 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
949 {
950         return m_texture;
951 }
952
953 int TestTexture2DArray::getArraySize (void) const
954 {
955         return m_texture.getNumLayers();
956 }
957
958
959 // TestTexture3D
960
961 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
962         : TestTexture   (format, width, height, depth)
963         , m_texture             (format, width, height, depth)
964 {
965         allocateLevels(m_texture);
966         TestTexture::populateLevels(getLevelsVector(m_texture));
967 }
968
969 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
970         : TestTexture   (format, width, height, depth)
971         , m_texture             (tcu::getUncompressedFormat(format), width, height, depth)
972 {
973         allocateLevels(m_texture);
974         TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
975 }
976
977 TestTexture3D::~TestTexture3D (void)
978 {
979 }
980
981 int TestTexture3D::getNumLevels (void) const
982 {
983         return m_texture.getNumLevels();
984 }
985
986 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
987 {
988         DE_ASSERT(layer == 0);
989         return m_texture.getLevel(level);
990 }
991
992 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
993 {
994         DE_ASSERT(layer == 0);
995         return m_texture.getLevel(level);
996 }
997
998 const tcu::Texture3D& TestTexture3D::getTexture (void) const
999 {
1000         return m_texture;
1001 }
1002
1003
1004 // TestTextureCube
1005
1006 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1007 {
1008         tcu::CUBEFACE_POSITIVE_X,
1009         tcu::CUBEFACE_NEGATIVE_X,
1010         tcu::CUBEFACE_POSITIVE_Y,
1011         tcu::CUBEFACE_NEGATIVE_Y,
1012         tcu::CUBEFACE_POSITIVE_Z,
1013         tcu::CUBEFACE_NEGATIVE_Z
1014 };
1015
1016 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1017         : TestTexture   (format, size, size, 1)
1018         , m_texture             (format, size)
1019 {
1020         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1021         {
1022                 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1023                 {
1024                         m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1025                         TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1026                 }
1027         }
1028 }
1029
1030 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1031         : TestTexture   (format, size, size, 1)
1032         , m_texture             (tcu::getUncompressedFormat(format), size)
1033 {
1034         std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1035
1036         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1037         {
1038                 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1039                 {
1040                         m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1041                         levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1042                 }
1043         }
1044
1045         TestTexture::populateCompressedLevels(format, levels);
1046 }
1047
1048 TestTextureCube::~TestTextureCube (void)
1049 {
1050 }
1051
1052 int TestTextureCube::getNumLevels (void) const
1053 {
1054         return m_texture.getNumLevels();
1055 }
1056
1057 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int face)
1058 {
1059         return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1060 }
1061
1062 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int face) const
1063 {
1064         return m_texture.getLevelFace(level, (tcu::CubeFace)face);
1065 }
1066
1067 int TestTextureCube::getArraySize (void) const
1068 {
1069         return (int)tcu::CUBEFACE_LAST;
1070 }
1071
1072 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1073 {
1074         return m_texture;
1075 }
1076
1077 // TestTextureCubeArray
1078
1079 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1080         : TestTexture   (format, size, size, arraySize)
1081         , m_texture             (format, size, arraySize)
1082 {
1083         allocateLevels(m_texture);
1084         TestTexture::populateLevels(getLevelsVector(m_texture));
1085 }
1086
1087 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1088         : TestTexture   (format, size, size, arraySize)
1089         , m_texture             (tcu::getUncompressedFormat(format), size, arraySize)
1090 {
1091         DE_ASSERT(arraySize % 6 == 0);
1092
1093         allocateLevels(m_texture);
1094
1095         std::vector<tcu::PixelBufferAccess> layers;
1096         for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1097                 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1098                         layers.push_back(getLevel(levelNdx, layerNdx));
1099
1100         TestTexture::populateCompressedLevels(format, layers);
1101 }
1102
1103 TestTextureCubeArray::~TestTextureCubeArray (void)
1104 {
1105 }
1106
1107 int TestTextureCubeArray::getNumLevels (void) const
1108 {
1109         return m_texture.getNumLevels();
1110 }
1111
1112 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1113 {
1114         const tcu::PixelBufferAccess    levelLayers     = m_texture.getLevel(level);
1115         const deUint32                                  layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1116         const deUint32                                  layerOffset     = layerSize * layer;
1117
1118         return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1119 }
1120
1121 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1122 {
1123         const tcu::ConstPixelBufferAccess       levelLayers     = m_texture.getLevel(level);
1124         const deUint32                                          layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1125         const deUint32                                          layerOffset     = layerSize * layer;
1126
1127         return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1128 }
1129
1130 int TestTextureCubeArray::getArraySize (void) const
1131 {
1132         return m_texture.getDepth();
1133 }
1134
1135 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1136 {
1137         return m_texture;
1138 }
1139
1140 } // pipeline
1141 } // vkt