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