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