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