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