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