Merge gerrit/vulkan-cts-1.0.1 into gerrit/vulkan-cts-1.0-dev
[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 namespace
325 {
326
327 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat)
328 {
329         VkImageAspectFlags imageAspectFlags = 0;
330
331         if (tcu::hasDepthComponent(textureFormat.order))
332                 imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
333
334         if (tcu::hasStencilComponent(textureFormat.order))
335                 imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
336
337         if (imageAspectFlags == 0)
338                 imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
339
340         return imageAspectFlags;
341 }
342
343 } // anonymous
344
345 void uploadTestTextureInternal (const DeviceInterface&                  vk,
346                                                                 VkDevice                                                device,
347                                                                 VkQueue                                                 queue,
348                                                                 deUint32                                                queueFamilyIndex,
349                                                                 Allocator&                                              allocator,
350                                                                 const TestTexture&                              srcTexture,
351                                                                 VkImage                                                 destImage)
352 {
353         deUint32                                                bufferSize;
354         Move<VkBuffer>                                  buffer;
355         de::MovePtr<Allocation>                 bufferAlloc;
356         Move<VkCommandPool>                             cmdPool;
357         Move<VkCommandBuffer>                   cmdBuffer;
358         Move<VkFence>                                   fence;
359         const VkImageAspectFlags                imageAspectFlags        = getImageAspectFlags(srcTexture.getTextureFormat());
360
361         // Calculate buffer size
362         bufferSize =  (srcTexture.isCompressed())? srcTexture.getCompressedSize(): srcTexture.getSize();
363
364         // Create source buffer
365         {
366                 const VkBufferCreateInfo bufferParams =
367                 {
368                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
369                         DE_NULL,                                                                        // const void*                  pNext;
370                         0u,                                                                                     // VkBufferCreateFlags  flags;
371                         bufferSize,                                                                     // VkDeviceSize                 size;
372                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
373                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
374                         0u,                                                                                     // deUint32                             queueFamilyIndexCount;
375                         DE_NULL,                                                                        // const deUint32*              pQueueFamilyIndices;
376                 };
377
378                 buffer          = createBuffer(vk, device, &bufferParams);
379                 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
380                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
381         }
382
383         // Create command pool and buffer
384         {
385                 const VkCommandPoolCreateInfo cmdPoolParams =
386                 {
387                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                      sType;
388                         DE_NULL,                                                                                // const void*                          pNext;
389                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
390                         queueFamilyIndex,                                                               // deUint32                                     queueFamilyIndex;
391                 };
392
393                 cmdPool = createCommandPool(vk, device, &cmdPoolParams);
394
395                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
396                 {
397                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
398                         DE_NULL,                                                                                // const void*                          pNext;
399                         *cmdPool,                                                                               // VkCommandPool                        commandPool;
400                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
401                         1u,                                                                                             // deUint32                                     bufferCount;
402                 };
403
404                 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
405         }
406
407         // Create fence
408         {
409                 const VkFenceCreateInfo fenceParams =
410                 {
411                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
412                         DE_NULL,                                                                        // const void*                  pNext;
413                         0u                                                                                      // VkFenceCreateFlags   flags;
414                 };
415
416                 fence = createFence(vk, device, &fenceParams);
417         }
418
419         // Barriers for copying buffer to image
420         const VkBufferMemoryBarrier preBufferBarrier =
421         {
422                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
423                 DE_NULL,                                                                        // const void*          pNext;
424                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
425                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
426                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
427                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
428                 *buffer,                                                                        // VkBuffer                     buffer;
429                 0u,                                                                                     // VkDeviceSize         offset;
430                 bufferSize                                                                      // VkDeviceSize         size;
431         };
432
433         const VkImageMemoryBarrier preImageBarrier =
434         {
435                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
436                 DE_NULL,                                                                                // const void*                          pNext;
437                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
438                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
439                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
440                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
441                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
442                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
443                 destImage,                                                                              // VkImage                                      image;
444                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
445                         imageAspectFlags,                                               // VkImageAspectFlags   aspectMask;
446                         0u,                                                                             // deUint32                             baseMipLevel;
447                         (deUint32)srcTexture.getNumLevels(),    // deUint32                             mipLevels;
448                         0u,                                                                             // deUint32                             baseArraySlice;
449                         (deUint32)srcTexture.getArraySize(),    // deUint32                             arraySize;
450                 }
451         };
452
453         const VkImageMemoryBarrier postImageBarrier =
454         {
455                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
456                 DE_NULL,                                                                                // const void*                          pNext;
457                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
458                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
459                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
460                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,               // VkImageLayout                        newLayout;
461                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
462                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
463                 destImage,                                                                              // VkImage                                      image;
464                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
465                         imageAspectFlags,                                               // VkImageAspectFlags   aspectMask;
466                         0u,                                                                             // deUint32                             baseMipLevel;
467                         (deUint32)srcTexture.getNumLevels(),    // deUint32                             mipLevels;
468                         0u,                                                                             // deUint32                             baseArraySlice;
469                         (deUint32)srcTexture.getArraySize(),    // deUint32                             arraySize;
470                 }
471         };
472
473         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
474         {
475                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
476                 DE_NULL,                                                                                // const void*                                          pNext;
477                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags;
478                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
479         };
480
481         const std::vector<VkBufferImageCopy>    copyRegions             = srcTexture.getBufferCopyRegions();
482
483         // Write buffer data
484         srcTexture.write(reinterpret_cast<deUint8*>(bufferAlloc->getHostPtr()));
485         flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
486
487         // Copy buffer to image
488         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
489         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
490         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), copyRegions.data());
491         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
492
493         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
494
495         const VkSubmitInfo submitInfo =
496         {
497                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
498                 DE_NULL,                                                // const void*                          pNext;
499                 0u,                                                             // deUint32                                     waitSemaphoreCount;
500                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
501                 DE_NULL,
502                 1u,                                                             // deUint32                                     commandBufferCount;
503                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
504                 0u,                                                             // deUint32                                     signalSemaphoreCount;
505                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
506         };
507
508         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
509         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
510 }
511
512 void uploadTestTexture (const DeviceInterface&                  vk,
513                                                 VkDevice                                                device,
514                                                 VkQueue                                                 queue,
515                                                 deUint32                                                queueFamilyIndex,
516                                                 Allocator&                                              allocator,
517                                                 const TestTexture&                              srcTexture,
518                                                 VkImage                                                 destImage)
519 {
520         if (tcu::isCombinedDepthStencilType(srcTexture.getTextureFormat().type))
521         {
522                 if (tcu::hasDepthComponent(srcTexture.getTextureFormat().order))
523                 {
524                         tcu::TextureFormat format;
525                         switch (srcTexture.getTextureFormat().type) {
526                         case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
527                                 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
528                                 break;
529                         case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
530                                 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
531                                 break;
532                         case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
533                                 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
534                                 break;
535                         default:
536                                 DE_ASSERT(0);
537                         }
538                         de::MovePtr<TestTexture> depthTexture   = srcTexture.copy(format);
539                         uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *depthTexture, destImage);
540                 }
541
542                 if (tcu::hasStencilComponent(srcTexture.getTextureFormat().order))
543                 {
544                         de::MovePtr<TestTexture> stencilTexture = srcTexture.copy(tcu::getEffectiveDepthStencilTextureFormat(srcTexture.getTextureFormat(), tcu::Sampler::MODE_STENCIL));
545                         uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, *stencilTexture, destImage);
546                 }
547         }
548         else
549                 uploadTestTextureInternal(vk, device, queue, queueFamilyIndex, allocator, srcTexture, destImage);
550 }
551
552 // Utilities for test textures
553
554 template<typename TcuTextureType>
555 void allocateLevels (TcuTextureType& texture)
556 {
557         for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
558                 texture.allocLevel(levelNdx);
559 }
560
561 template<typename TcuTextureType>
562 std::vector<tcu::PixelBufferAccess> getLevelsVector (const TcuTextureType& texture)
563 {
564         std::vector<tcu::PixelBufferAccess> levels(texture.getNumLevels());
565
566         for (int levelNdx = 0; levelNdx < texture.getNumLevels(); levelNdx++)
567                 levels[levelNdx] = *reinterpret_cast<const tcu::PixelBufferAccess*>(&texture.getLevel(levelNdx));
568
569         return levels;
570 }
571
572 // TestTexture
573
574 TestTexture::TestTexture (const tcu::TextureFormat& format, int width, int height, int depth)
575 {
576         DE_ASSERT(width >= 1);
577         DE_ASSERT(height >= 1);
578         DE_ASSERT(depth >= 1);
579
580         DE_UNREF(format);
581         DE_UNREF(width);
582         DE_UNREF(height);
583         DE_UNREF(depth);
584 }
585
586 TestTexture::TestTexture (const tcu::CompressedTexFormat& format, int width, int height, int depth)
587 {
588         DE_ASSERT(width >= 1);
589         DE_ASSERT(height >= 1);
590         DE_ASSERT(depth >= 1);
591
592         DE_UNREF(format);
593         DE_UNREF(width);
594         DE_UNREF(height);
595         DE_UNREF(depth);
596 }
597
598 TestTexture::~TestTexture (void)
599 {
600         for (size_t levelNdx = 0; levelNdx < m_compressedLevels.size(); levelNdx++)
601                 delete m_compressedLevels[levelNdx];
602 }
603
604 deUint32 TestTexture::getSize (void) const
605 {
606         std::vector<deUint32>   offsetMultiples;
607         deUint32                                textureSize = 0;
608
609         offsetMultiples.push_back(4);
610         offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
611
612         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
613         {
614                 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
615                 {
616                         const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
617                         textureSize = getNextMultiple(offsetMultiples, textureSize);
618                         textureSize += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
619                 }
620         }
621
622         return textureSize;
623 }
624
625 deUint32 TestTexture::getCompressedSize (void) const
626 {
627         if (!isCompressed())
628                 throw tcu::InternalError("Texture is not compressed");
629
630         std::vector<deUint32>   offsetMultiples;
631         deUint32                                textureSize                     = 0;
632
633         offsetMultiples.push_back(4);
634         offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
635
636         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
637         {
638                 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
639                 {
640                         textureSize = getNextMultiple(offsetMultiples, textureSize);
641                         textureSize += getCompressedLevel(levelNdx, layerNdx).getDataSize();
642                 }
643         }
644
645         return textureSize;
646 }
647
648 tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer)
649 {
650         DE_ASSERT(level >= 0 && level < getNumLevels());
651         DE_ASSERT(layer >= 0 && layer < getArraySize());
652
653         return *m_compressedLevels[level * getArraySize() + layer];
654 }
655
656 const tcu::CompressedTexture& TestTexture::getCompressedLevel (int level, int layer) const
657 {
658         DE_ASSERT(level >= 0 && level < getNumLevels());
659         DE_ASSERT(layer >= 0 && layer < getArraySize());
660
661         return *m_compressedLevels[level * getArraySize() + layer];
662 }
663
664 std::vector<VkBufferImageCopy> TestTexture::getBufferCopyRegions (void) const
665 {
666         std::vector<deUint32>                   offsetMultiples;
667         std::vector<VkBufferImageCopy>  regions;
668         deUint32                                                layerDataOffset = 0;
669
670         offsetMultiples.push_back(4);
671
672         if (isCompressed())
673         {
674                 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
675
676                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
677                 {
678                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
679                         {
680                                 const tcu::CompressedTexture& level = getCompressedLevel(levelNdx, layerNdx);
681                                 tcu::IVec3 blockPixelSize                       = getBlockPixelSize(level.getFormat());
682                                 layerDataOffset                                         = getNextMultiple(offsetMultiples, layerDataOffset);
683
684                                 const VkBufferImageCopy layerRegion =
685                                 {
686                                         layerDataOffset,                                                                                                        // VkDeviceSize                         bufferOffset;
687                                         (deUint32)getNextMultiple(blockPixelSize.x(), level.getWidth()),        // deUint32                                     bufferRowLength;
688                                         (deUint32)getNextMultiple(blockPixelSize.y(), level.getHeight()),       // deUint32                                     bufferImageHeight;
689                                         {                                                                                                                                       // VkImageSubresourceLayers     imageSubresource;
690                                                 VK_IMAGE_ASPECT_COLOR_BIT,
691                                                 (deUint32)levelNdx,
692                                                 (deUint32)layerNdx,
693                                                 1u
694                                         },
695                                         { 0u, 0u, 0u },                                                 // VkOffset3D                           imageOffset;
696                                         {                                                                               // VkExtent3D                           imageExtent;
697                                                 (deUint32)level.getWidth(),
698                                                 (deUint32)level.getHeight(),
699                                                 (deUint32)level.getDepth()
700                                         }
701                                 };
702
703                                 regions.push_back(layerRegion);
704                                 layerDataOffset += level.getDataSize();
705                         }
706                 }
707         }
708         else
709         {
710                 std::vector<VkImageAspectFlags> imageAspects;
711                 tcu::TextureFormat                              textureFormat   = getTextureFormat();
712
713                 if (tcu::hasDepthComponent(textureFormat.order))
714                         imageAspects.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
715
716                 if (tcu::hasStencilComponent(textureFormat.order))
717                         imageAspects.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
718
719                 if (imageAspects.empty())
720                         imageAspects.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
721
722                 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
723
724                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
725                 {
726                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
727                         {
728                                 const tcu::ConstPixelBufferAccess level = getLevel(levelNdx, layerNdx);
729
730                                 layerDataOffset = getNextMultiple(offsetMultiples, layerDataOffset);
731
732                                 for (size_t aspectIndex = 0; aspectIndex < imageAspects.size(); ++aspectIndex)
733                                 {
734                                         const VkBufferImageCopy layerRegion =
735                                         {
736                                                 layerDataOffset,                                                // VkDeviceSize                         bufferOffset;
737                                                 (deUint32)level.getWidth(),                             // deUint32                                     bufferRowLength;
738                                                 (deUint32)level.getHeight(),                    // deUint32                                     bufferImageHeight;
739                                                 {                                                                               // VkImageSubresourceLayers     imageSubresource;
740                                                         imageAspects[aspectIndex],
741                                                         (deUint32)levelNdx,
742                                                         (deUint32)layerNdx,
743                                                         1u
744                                                 },
745                                                 { 0u, 0u, 0u },                                                 // VkOffset3D                   imageOffset;
746                                                 {                                                                               // VkExtent3D                   imageExtent;
747                                                         (deUint32)level.getWidth(),
748                                                         (deUint32)level.getHeight(),
749                                                         (deUint32)level.getDepth()
750                                                 }
751                                         };
752
753                                         regions.push_back(layerRegion);
754                                 }
755                                 layerDataOffset += level.getWidth() * level.getHeight() * level.getDepth() * level.getFormat().getPixelSize();
756                         }
757                 }
758         }
759
760         return regions;
761 }
762
763 void TestTexture::write (deUint8* destPtr) const
764 {
765         std::vector<deUint32>   offsetMultiples;
766         deUint32                                levelOffset             = 0;
767
768         offsetMultiples.push_back(4);
769
770         if (isCompressed())
771         {
772                 offsetMultiples.push_back(tcu::getBlockSize(getCompressedLevel(0, 0).getFormat()));
773
774                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
775                 {
776                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
777                         {
778                                 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
779
780                                 const tcu::CompressedTexture&           compressedTex   = getCompressedLevel(levelNdx, layerNdx);
781
782                                 deMemcpy(destPtr + levelOffset, compressedTex.getData(), compressedTex.getDataSize());
783                                 levelOffset += compressedTex.getDataSize();
784                         }
785                 }
786         }
787         else
788         {
789                 offsetMultiples.push_back(getLevel(0, 0).getFormat().getPixelSize());
790
791                 for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
792                 {
793                         for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
794                         {
795                                 levelOffset = getNextMultiple(offsetMultiples, levelOffset);
796
797                                 const tcu::ConstPixelBufferAccess       srcAccess               = getLevel(levelNdx, layerNdx);
798                                 const tcu::PixelBufferAccess            destAccess              (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), destPtr + levelOffset);
799
800                                 tcu::copy(destAccess, srcAccess);
801                                 levelOffset += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
802                         }
803                 }
804         }
805 }
806
807 void TestTexture::copyToTexture (TestTexture& destTexture) const
808 {
809         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
810                 for (int layerNdx = 0; layerNdx < getArraySize(); layerNdx++)
811                         tcu::copy(destTexture.getLevel(levelNdx, layerNdx), getLevel(levelNdx, layerNdx));
812 }
813
814 void TestTexture::populateLevels (const std::vector<tcu::PixelBufferAccess>& levels)
815 {
816         for (size_t levelNdx = 0; levelNdx < levels.size(); levelNdx++)
817                 TestTexture::fillWithGradient(levels[levelNdx]);
818 }
819
820 void TestTexture::populateCompressedLevels (tcu::CompressedTexFormat format, const std::vector<tcu::PixelBufferAccess>& decompressedLevels)
821 {
822         // Generate random compressed data and update decompressed data
823
824         de::Random random(123);
825
826         for (size_t levelNdx = 0; levelNdx < decompressedLevels.size(); levelNdx++)
827         {
828                 const tcu::PixelBufferAccess    level                           = decompressedLevels[levelNdx];
829                 tcu::CompressedTexture*                 compressedLevel         = new tcu::CompressedTexture(format, level.getWidth(), level.getHeight(), level.getDepth());
830                 deUint8* const                                  compressedData          = (deUint8*)compressedLevel->getData();
831
832                 if (tcu::isAstcFormat(format))
833                 {
834                         // \todo [2016-01-20 pyry] Comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
835                         tcu::astc::generateRandomValidBlocks(compressedData, compressedLevel->getDataSize()/tcu::astc::BLOCK_SIZE_BYTES,
836                                                                                                  format, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
837                 }
838                 else
839                 {
840                         // Generate random compressed data
841                         // Random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
842                         if (format != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
843                                 for (int byteNdx = 0; byteNdx < compressedLevel->getDataSize(); byteNdx++)
844                                         compressedData[byteNdx] = 0xFF & random.getUint32();
845                 }
846
847                 m_compressedLevels.push_back(compressedLevel);
848
849                 // Store decompressed data
850                 compressedLevel->decompress(level, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
851         }
852 }
853
854 void TestTexture::fillWithGradient (const tcu::PixelBufferAccess& levelAccess)
855 {
856         const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(levelAccess.getFormat());
857         tcu::fillWithComponentGradients(levelAccess, formatInfo.valueMin, formatInfo.valueMax);
858 }
859
860 // TestTexture1D
861
862 TestTexture1D::TestTexture1D (const tcu::TextureFormat& format, int width)
863         : TestTexture   (format, width, 1, 1)
864         , m_texture             (format, width)
865 {
866         allocateLevels(m_texture);
867         TestTexture::populateLevels(getLevelsVector(m_texture));
868 }
869
870 TestTexture1D::TestTexture1D (const tcu::CompressedTexFormat& format, int width)
871         : TestTexture   (format, width, 1, 1)
872         , m_texture             (tcu::getUncompressedFormat(format), width)
873 {
874         allocateLevels(m_texture);
875         TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
876 }
877
878 TestTexture1D::~TestTexture1D (void)
879 {
880 }
881
882 int TestTexture1D::getNumLevels (void) const
883 {
884         return m_texture.getNumLevels();
885 }
886
887 tcu::PixelBufferAccess TestTexture1D::getLevel (int level, int layer)
888 {
889         DE_ASSERT(layer == 0);
890         DE_UNREF(layer);
891         return m_texture.getLevel(level);
892 }
893
894 const tcu::ConstPixelBufferAccess TestTexture1D::getLevel (int level, int layer) const
895 {
896         DE_ASSERT(layer == 0);
897         DE_UNREF(layer);
898         return m_texture.getLevel(level);
899 }
900
901 const tcu::Texture1D& TestTexture1D::getTexture (void) const
902 {
903         return m_texture;
904 }
905
906 tcu::Texture1D& TestTexture1D::getTexture (void)
907 {
908         return m_texture;
909 }
910
911 de::MovePtr<TestTexture> TestTexture1D::copy(const tcu::TextureFormat format) const
912 {
913         DE_ASSERT(!isCompressed());
914
915         de::MovePtr<TestTexture>        texture (new TestTexture1D(format, m_texture.getWidth()));
916
917         copyToTexture(*texture);
918
919         return texture;
920 }
921
922 // TestTexture1DArray
923
924 TestTexture1DArray::TestTexture1DArray (const tcu::TextureFormat& format, int width, int arraySize)
925         : TestTexture   (format, width, 1, arraySize)
926         , m_texture             (format, width, arraySize)
927 {
928         allocateLevels(m_texture);
929         TestTexture::populateLevels(getLevelsVector(m_texture));
930 }
931
932 TestTexture1DArray::TestTexture1DArray (const tcu::CompressedTexFormat& format, int width, int arraySize)
933         : TestTexture   (format, width, 1, arraySize)
934         , m_texture             (tcu::getUncompressedFormat(format), width, arraySize)
935 {
936         allocateLevels(m_texture);
937
938         std::vector<tcu::PixelBufferAccess> layers;
939         for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
940                 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
941                         layers.push_back(getLevel(levelNdx, layerNdx));
942
943         TestTexture::populateCompressedLevels(format, layers);
944 }
945
946 TestTexture1DArray::~TestTexture1DArray (void)
947 {
948 }
949
950 int TestTexture1DArray::getNumLevels (void) const
951 {
952         return m_texture.getNumLevels();
953 }
954
955 tcu::PixelBufferAccess TestTexture1DArray::getLevel (int level, int layer)
956 {
957         const tcu::PixelBufferAccess    levelLayers     = m_texture.getLevel(level);
958         const deUint32                                  layerSize       = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
959         const deUint32                                  layerOffset     = layerSize * layer;
960
961         return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
962 }
963
964 const tcu::ConstPixelBufferAccess TestTexture1DArray::getLevel (int level, int layer) const
965 {
966         const tcu::ConstPixelBufferAccess       levelLayers     = m_texture.getLevel(level);
967         const deUint32                                          layerSize       = levelLayers.getWidth() * levelLayers.getFormat().getPixelSize();
968         const deUint32                                          layerOffset     = layerSize * layer;
969
970         return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), 1, 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
971 }
972
973 const tcu::Texture1DArray& TestTexture1DArray::getTexture (void) const
974 {
975         return m_texture;
976 }
977
978 tcu::Texture1DArray& TestTexture1DArray::getTexture (void)
979 {
980         return m_texture;
981 }
982
983 int TestTexture1DArray::getArraySize (void) const
984 {
985         return m_texture.getNumLayers();
986 }
987
988 de::MovePtr<TestTexture> TestTexture1DArray::copy(const tcu::TextureFormat format) const
989 {
990         DE_ASSERT(!isCompressed());
991
992         de::MovePtr<TestTexture>        texture (new TestTexture1DArray(format, m_texture.getWidth(), getArraySize()));
993
994         copyToTexture(*texture);
995
996         return texture;
997 }
998
999 // TestTexture2D
1000
1001 TestTexture2D::TestTexture2D (const tcu::TextureFormat& format, int width, int height)
1002         : TestTexture   (format, width, height, 1)
1003         , m_texture             (format, width, height)
1004 {
1005         allocateLevels(m_texture);
1006         TestTexture::populateLevels(getLevelsVector(m_texture));
1007 }
1008
1009 TestTexture2D::TestTexture2D (const tcu::CompressedTexFormat& format, int width, int height)
1010         : TestTexture   (format, width, height, 1)
1011         , m_texture             (tcu::getUncompressedFormat(format), width, height)
1012 {
1013         allocateLevels(m_texture);
1014         TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1015 }
1016
1017 TestTexture2D::~TestTexture2D (void)
1018 {
1019 }
1020
1021 int TestTexture2D::getNumLevels (void) const
1022 {
1023         return m_texture.getNumLevels();
1024 }
1025
1026 tcu::PixelBufferAccess TestTexture2D::getLevel (int level, int layer)
1027 {
1028         DE_ASSERT(layer == 0);
1029         DE_UNREF(layer);
1030         return m_texture.getLevel(level);
1031 }
1032
1033 const tcu::ConstPixelBufferAccess TestTexture2D::getLevel (int level, int layer) const
1034 {
1035         DE_ASSERT(layer == 0);
1036         DE_UNREF(layer);
1037         return m_texture.getLevel(level);
1038 }
1039
1040 const tcu::Texture2D& TestTexture2D::getTexture (void) const
1041 {
1042         return m_texture;
1043 }
1044
1045 tcu::Texture2D& TestTexture2D::getTexture (void)
1046 {
1047         return m_texture;
1048 }
1049
1050 de::MovePtr<TestTexture> TestTexture2D::copy(const tcu::TextureFormat format) const
1051 {
1052         DE_ASSERT(!isCompressed());
1053
1054         de::MovePtr<TestTexture>        texture (new TestTexture2D(format, m_texture.getWidth(), m_texture.getHeight()));
1055
1056         copyToTexture(*texture);
1057
1058         return texture;
1059 }
1060
1061 // TestTexture2DArray
1062
1063 TestTexture2DArray::TestTexture2DArray (const tcu::TextureFormat& format, int width, int height, int arraySize)
1064         : TestTexture   (format, width, height, arraySize)
1065         , m_texture             (format, width, height, arraySize)
1066 {
1067         allocateLevels(m_texture);
1068         TestTexture::populateLevels(getLevelsVector(m_texture));
1069 }
1070
1071 TestTexture2DArray::TestTexture2DArray (const tcu::CompressedTexFormat& format, int width, int height, int arraySize)
1072         : TestTexture   (format, width, height, arraySize)
1073         , m_texture             (tcu::getUncompressedFormat(format), width, height, arraySize)
1074 {
1075         allocateLevels(m_texture);
1076
1077         std::vector<tcu::PixelBufferAccess> layers;
1078         for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1079                 for (int layerNdx = 0; layerNdx < m_texture.getNumLayers(); layerNdx++)
1080                         layers.push_back(getLevel(levelNdx, layerNdx));
1081
1082         TestTexture::populateCompressedLevels(format, layers);
1083 }
1084
1085 TestTexture2DArray::~TestTexture2DArray (void)
1086 {
1087 }
1088
1089 int TestTexture2DArray::getNumLevels (void) const
1090 {
1091         return m_texture.getNumLevels();
1092 }
1093
1094 tcu::PixelBufferAccess TestTexture2DArray::getLevel (int level, int layer)
1095 {
1096         const tcu::PixelBufferAccess    levelLayers     = m_texture.getLevel(level);
1097         const deUint32                                  layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1098         const deUint32                                  layerOffset     = layerSize * layer;
1099
1100         return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1101 }
1102
1103 const tcu::ConstPixelBufferAccess TestTexture2DArray::getLevel (int level, int layer) const
1104 {
1105         const tcu::ConstPixelBufferAccess       levelLayers     = m_texture.getLevel(level);
1106         const deUint32                                          layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1107         const deUint32                                          layerOffset     = layerSize * layer;
1108
1109         return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1110 }
1111
1112 const tcu::Texture2DArray& TestTexture2DArray::getTexture (void) const
1113 {
1114         return m_texture;
1115 }
1116
1117 tcu::Texture2DArray& TestTexture2DArray::getTexture (void)
1118 {
1119         return m_texture;
1120 }
1121
1122 int TestTexture2DArray::getArraySize (void) const
1123 {
1124         return m_texture.getNumLayers();
1125 }
1126
1127 de::MovePtr<TestTexture> TestTexture2DArray::copy(const tcu::TextureFormat format) const
1128 {
1129         DE_ASSERT(!isCompressed());
1130
1131         de::MovePtr<TestTexture>        texture (new TestTexture2DArray(format, m_texture.getWidth(), m_texture.getHeight(), getArraySize()));
1132
1133         copyToTexture(*texture);
1134
1135         return texture;
1136 }
1137
1138 // TestTexture3D
1139
1140 TestTexture3D::TestTexture3D (const tcu::TextureFormat& format, int width, int height, int depth)
1141         : TestTexture   (format, width, height, depth)
1142         , m_texture             (format, width, height, depth)
1143 {
1144         allocateLevels(m_texture);
1145         TestTexture::populateLevels(getLevelsVector(m_texture));
1146 }
1147
1148 TestTexture3D::TestTexture3D (const tcu::CompressedTexFormat& format, int width, int height, int depth)
1149         : TestTexture   (format, width, height, depth)
1150         , m_texture             (tcu::getUncompressedFormat(format), width, height, depth)
1151 {
1152         allocateLevels(m_texture);
1153         TestTexture::populateCompressedLevels(format, getLevelsVector(m_texture));
1154 }
1155
1156 TestTexture3D::~TestTexture3D (void)
1157 {
1158 }
1159
1160 int TestTexture3D::getNumLevels (void) const
1161 {
1162         return m_texture.getNumLevels();
1163 }
1164
1165 tcu::PixelBufferAccess TestTexture3D::getLevel (int level, int layer)
1166 {
1167         DE_ASSERT(layer == 0);
1168         DE_UNREF(layer);
1169         return m_texture.getLevel(level);
1170 }
1171
1172 const tcu::ConstPixelBufferAccess TestTexture3D::getLevel (int level, int layer) const
1173 {
1174         DE_ASSERT(layer == 0);
1175         DE_UNREF(layer);
1176         return m_texture.getLevel(level);
1177 }
1178
1179 const tcu::Texture3D& TestTexture3D::getTexture (void) const
1180 {
1181         return m_texture;
1182 }
1183
1184 tcu::Texture3D& TestTexture3D::getTexture (void)
1185 {
1186         return m_texture;
1187 }
1188
1189 de::MovePtr<TestTexture> TestTexture3D::copy(const tcu::TextureFormat format) const
1190 {
1191         DE_ASSERT(!isCompressed());
1192
1193         de::MovePtr<TestTexture>        texture (new TestTexture3D(format, m_texture.getWidth(), m_texture.getHeight(), m_texture.getDepth()));
1194
1195         copyToTexture(*texture);
1196
1197         return texture;
1198 }
1199
1200 // TestTextureCube
1201
1202 const static tcu::CubeFace tcuFaceMapping[tcu::CUBEFACE_LAST] =
1203 {
1204         tcu::CUBEFACE_POSITIVE_X,
1205         tcu::CUBEFACE_NEGATIVE_X,
1206         tcu::CUBEFACE_POSITIVE_Y,
1207         tcu::CUBEFACE_NEGATIVE_Y,
1208         tcu::CUBEFACE_POSITIVE_Z,
1209         tcu::CUBEFACE_NEGATIVE_Z
1210 };
1211
1212 TestTextureCube::TestTextureCube (const tcu::TextureFormat& format, int size)
1213         : TestTexture   (format, size, size, 1)
1214         , m_texture             (format, size)
1215 {
1216         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1217         {
1218                 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1219                 {
1220                         m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1221                         TestTexture::fillWithGradient(m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]));
1222                 }
1223         }
1224 }
1225
1226 TestTextureCube::TestTextureCube (const tcu::CompressedTexFormat& format, int size)
1227         : TestTexture   (format, size, size, 1)
1228         , m_texture             (tcu::getUncompressedFormat(format), size)
1229 {
1230         std::vector<tcu::PixelBufferAccess> levels(m_texture.getNumLevels() * tcu::CUBEFACE_LAST);
1231
1232         for (int levelNdx = 0; levelNdx < getNumLevels(); levelNdx++)
1233         {
1234                 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
1235                 {
1236                         m_texture.allocLevel(tcuFaceMapping[faceNdx], levelNdx);
1237                         levels[levelNdx * tcu::CUBEFACE_LAST + faceNdx] = m_texture.getLevelFace(levelNdx, tcuFaceMapping[faceNdx]);
1238                 }
1239         }
1240
1241         TestTexture::populateCompressedLevels(format, levels);
1242 }
1243
1244 TestTextureCube::~TestTextureCube (void)
1245 {
1246 }
1247
1248 int TestTextureCube::getNumLevels (void) const
1249 {
1250         return m_texture.getNumLevels();
1251 }
1252
1253 tcu::PixelBufferAccess TestTextureCube::getLevel (int level, int layer)
1254 {
1255         return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1256 }
1257
1258 const tcu::ConstPixelBufferAccess TestTextureCube::getLevel (int level, int layer) const
1259 {
1260         return m_texture.getLevelFace(level, tcuFaceMapping[layer]);
1261 }
1262
1263 int TestTextureCube::getArraySize (void) const
1264 {
1265         return (int)tcu::CUBEFACE_LAST;
1266 }
1267
1268 const tcu::TextureCube& TestTextureCube::getTexture (void) const
1269 {
1270         return m_texture;
1271 }
1272
1273 tcu::TextureCube& TestTextureCube::getTexture (void)
1274 {
1275         return m_texture;
1276 }
1277
1278 de::MovePtr<TestTexture> TestTextureCube::copy(const tcu::TextureFormat format) const
1279 {
1280         DE_ASSERT(!isCompressed());
1281
1282         de::MovePtr<TestTexture>        texture (new TestTextureCube(format, m_texture.getSize()));
1283
1284         copyToTexture(*texture);
1285
1286         return texture;
1287 }
1288
1289 // TestTextureCubeArray
1290
1291 TestTextureCubeArray::TestTextureCubeArray (const tcu::TextureFormat& format, int size, int arraySize)
1292         : TestTexture   (format, size, size, arraySize)
1293         , m_texture             (format, size, arraySize)
1294 {
1295         allocateLevels(m_texture);
1296         TestTexture::populateLevels(getLevelsVector(m_texture));
1297 }
1298
1299 TestTextureCubeArray::TestTextureCubeArray (const tcu::CompressedTexFormat& format, int size, int arraySize)
1300         : TestTexture   (format, size, size, arraySize)
1301         , m_texture             (tcu::getUncompressedFormat(format), size, arraySize)
1302 {
1303         DE_ASSERT(arraySize % 6 == 0);
1304
1305         allocateLevels(m_texture);
1306
1307         std::vector<tcu::PixelBufferAccess> layers;
1308         for (int levelNdx = 0; levelNdx < m_texture.getNumLevels(); levelNdx++)
1309                 for (int layerNdx = 0; layerNdx < m_texture.getDepth(); layerNdx++)
1310                         layers.push_back(getLevel(levelNdx, layerNdx));
1311
1312         TestTexture::populateCompressedLevels(format, layers);
1313 }
1314
1315 TestTextureCubeArray::~TestTextureCubeArray (void)
1316 {
1317 }
1318
1319 int TestTextureCubeArray::getNumLevels (void) const
1320 {
1321         return m_texture.getNumLevels();
1322 }
1323
1324 tcu::PixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer)
1325 {
1326         const tcu::PixelBufferAccess    levelLayers     = m_texture.getLevel(level);
1327         const deUint32                                  layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1328         const deUint32                                  layerOffset     = layerSize * layer;
1329
1330         return tcu::PixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1331 }
1332
1333 const tcu::ConstPixelBufferAccess TestTextureCubeArray::getLevel (int level, int layer) const
1334 {
1335         const tcu::ConstPixelBufferAccess       levelLayers     = m_texture.getLevel(level);
1336         const deUint32                                          layerSize       = levelLayers.getWidth() * levelLayers.getHeight() * levelLayers.getFormat().getPixelSize();
1337         const deUint32                                          layerOffset     = layerSize * layer;
1338
1339         return tcu::ConstPixelBufferAccess(levelLayers.getFormat(), levelLayers.getWidth(), levelLayers.getHeight(), 1, (deUint8*)levelLayers.getDataPtr() + layerOffset);
1340 }
1341
1342 int TestTextureCubeArray::getArraySize (void) const
1343 {
1344         return m_texture.getDepth();
1345 }
1346
1347 const tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void) const
1348 {
1349         return m_texture;
1350 }
1351
1352 tcu::TextureCubeArray& TestTextureCubeArray::getTexture (void)
1353 {
1354         return m_texture;
1355 }
1356
1357 de::MovePtr<TestTexture> TestTextureCubeArray::copy(const tcu::TextureFormat format) const
1358 {
1359         DE_ASSERT(!isCompressed());
1360
1361         de::MovePtr<TestTexture>        texture (new TestTextureCubeArray(format, m_texture.getSize(), getArraySize()));
1362
1363         copyToTexture(*texture);
1364
1365         return texture;
1366 }
1367
1368 } // pipeline
1369 } // vkt