Fix memory leaks in dEQP-VK.api.invariance.random
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiMemoryRequirementInvarianceTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  * Copyright (c) 2018 The Khronos Group Inc.
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
22 #include "vktApiMemoryRequirementInvarianceTests.hpp"
23 #include "vktApiBufferAndImageAllocationUtil.hpp"
24 #include "deRandom.h"
25 #include "tcuTestLog.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "vkMemUtil.hpp"
28 #include "vkRefUtil.hpp"
29 #include "vkImageUtil.hpp"
30
31
32 namespace vkt
33 {
34 namespace api
35 {
36
37 using namespace vk;
38
39 // Number of items to allocate
40 const unsigned int              testCycles                                                              = 1000u;
41
42 // All legal memory combinations (spec chapter 10.2: Device Memory)
43 const unsigned int              legalMemoryTypeCount                                    = 11u;
44 const MemoryRequirement legalMemoryTypes[legalMemoryTypeCount]  =
45 {
46         MemoryRequirement::Any,
47         MemoryRequirement::HostVisible  | MemoryRequirement::Coherent,
48         MemoryRequirement::HostVisible  | MemoryRequirement::Cached,
49         MemoryRequirement::HostVisible  | MemoryRequirement::Cached                     | MemoryRequirement::Coherent,
50         MemoryRequirement::Local,
51         MemoryRequirement::Local                | MemoryRequirement::HostVisible        | MemoryRequirement::Coherent,
52         MemoryRequirement::Local                | MemoryRequirement::HostVisible        | MemoryRequirement::Cached,
53         MemoryRequirement::Local                | MemoryRequirement::HostVisible        | MemoryRequirement::Cached             | MemoryRequirement::Coherent,
54         MemoryRequirement::Local                | MemoryRequirement::LazilyAllocated,
55         MemoryRequirement::Protected,
56         MemoryRequirement::Protected    | MemoryRequirement::Local
57 };
58
59 class IObjectAllocator
60 {
61 public:
62                                         IObjectAllocator        ()      {};
63         virtual                 ~IObjectAllocator       ()      {};
64         virtual void    allocate                        (Context&       context)        = 0;
65         virtual void    deallocate                      (Context&       context)        = 0;
66         virtual size_t  getSize                         (Context&       context)        = 0;
67 };
68
69 class BufferAllocator : public IObjectAllocator
70 {
71 public:
72                                         BufferAllocator         (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes);
73         virtual                 ~BufferAllocator        ();
74         virtual void    allocate                        (Context&       context);
75         virtual void    deallocate                      (Context&       context);
76         virtual size_t  getSize                         (Context&       context);
77 private:
78         bool                                    m_dedicated;
79         Move<VkBuffer>                  m_buffer;
80         VkDeviceSize                    m_size;
81         VkBufferUsageFlags              m_usage;
82         int                                             m_memoryType;
83         de::MovePtr<Allocation> m_bufferAlloc;
84 };
85
86 BufferAllocator::BufferAllocator (deRandom& random, deBool dedicated, std::vector<int>& memoryTypes)
87 {
88         // If dedicated allocation is supported, randomly pick it
89         m_dedicated             = dedicated && deRandom_getBool(&random);
90         // Random buffer sizes to find potential issues caused by strange alignment
91         m_size                  = (deRandom_getUint32(&random) % 1024) + 7;
92         // Pick a random usage from the 9 VkBufferUsageFlags.
93         m_usage                 = 1 << (deRandom_getUint32(&random) % 9);
94         // Pick random memory type from the supported ones
95         m_memoryType    = memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
96 }
97
98 BufferAllocator::~BufferAllocator ()
99 {
100 }
101
102 void BufferAllocator::allocate (Context& context)
103 {
104         Allocator&                                              memAlloc        = context.getDefaultAllocator();
105         de::MovePtr<IBufferAllocator>   allocator;
106         MemoryRequirement                               requirement     = legalMemoryTypes[m_memoryType];
107
108         if (m_dedicated)
109                 allocator = de::MovePtr<IBufferAllocator>(new BufferDedicatedAllocation);
110         else
111                 allocator = de::MovePtr<IBufferAllocator>(new BufferSuballocation);
112
113         allocator->createTestBuffer(
114                 m_size,
115                 m_usage,
116                 context,
117                 memAlloc,
118                 m_buffer,
119                 requirement,
120                 m_bufferAlloc);
121 }
122
123 void BufferAllocator::deallocate (Context& context)
124 {
125         const DeviceInterface&  vk              = context.getDeviceInterface();
126         const vk::VkDevice&             device  = context.getDevice();
127
128         vk.destroyBuffer(device, m_buffer.disown(), DE_NULL);
129         m_bufferAlloc.clear();
130 }
131
132 size_t BufferAllocator::getSize (Context &context)
133 {
134         const DeviceInterface&  vk              = context.getDeviceInterface();
135         const vk::VkDevice&             device  = context.getDevice();
136         VkMemoryRequirements    memReq;
137
138         vk.getBufferMemoryRequirements(device, *m_buffer, &memReq);
139
140         return (size_t)memReq.size;
141 }
142
143 class ImageAllocator : public IObjectAllocator
144 {
145 public:
146                                         ImageAllocator  (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes);
147         virtual                 ~ImageAllocator ();
148         virtual void    allocate                (Context&       context);
149         virtual void    deallocate              (Context&       context);
150         virtual size_t  getSize                 (Context&       context);
151 private:
152         deBool                                  m_dedicated;
153         deBool                                  m_linear;
154         Move<vk::VkImage>               m_image;
155         tcu::IVec2                              m_size;
156         vk::VkFormat                    m_colorFormat;
157         de::MovePtr<Allocation> m_imageAlloc;
158         int                                             m_memoryType;
159 };
160
161 ImageAllocator::ImageAllocator (deRandom& random, deBool dedicated, std::vector<int>& linearformats, std::vector<int>& optimalformats, std::vector<int>& memoryTypes)
162 {
163         // If dedicated allocation is supported, pick it randomly
164         m_dedicated             = dedicated && deRandom_getBool(&random);
165         // If linear formats are supported, pick it randomly
166         m_linear                = (linearformats.size() > 0) && deRandom_getBool(&random);
167
168         if (m_linear)
169                 m_colorFormat = (VkFormat)linearformats[deRandom_getUint32(&random) % linearformats.size()];
170         else
171                 m_colorFormat = (VkFormat)optimalformats[deRandom_getUint32(&random) % optimalformats.size()];
172
173         int     widthAlignment  = (isYCbCr420Format(m_colorFormat) || isYCbCr422Format(m_colorFormat)) ? 2 : 1;
174         int     heightAlignment = isYCbCr420Format(m_colorFormat) ? 2 : 1;
175
176         // Random small size for causing potential alignment issues
177         m_size                  = tcu::IVec2((deRandom_getUint32(&random) % 16 + 3) & ~(widthAlignment - 1),
178                                                                  (deRandom_getUint32(&random) % 16 + 3) & ~(heightAlignment - 1));
179         // Pick random memory type from the supported set
180         m_memoryType    = memoryTypes[deRandom_getUint32(&random) % memoryTypes.size()];
181 }
182
183 ImageAllocator::~ImageAllocator ()
184 {
185 }
186
187 void ImageAllocator::allocate (Context& context)
188 {
189         Allocator&                                              memAlloc        = context.getDefaultAllocator();
190         de::MovePtr<IImageAllocator>    allocator;
191         MemoryRequirement                               requirement     = legalMemoryTypes[m_memoryType];
192
193         if (m_dedicated)
194                 allocator = de::MovePtr<IImageAllocator>(new ImageDedicatedAllocation);
195         else
196                 allocator = de::MovePtr<IImageAllocator>(new ImageSuballocation);
197
198         allocator->createTestImage(
199                 m_size,
200                 m_colorFormat,
201                 context,
202                 memAlloc,
203                 m_image,
204                 requirement,
205                 m_imageAlloc,
206                 m_linear ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL);
207 }
208
209 void ImageAllocator::deallocate (Context& context)
210 {
211         const DeviceInterface&  vk              = context.getDeviceInterface();
212         const VkDevice&                 device  = context.getDevice();
213
214         vk.destroyImage(device, m_image.disown(), DE_NULL);
215         m_imageAlloc.clear();
216 }
217
218 size_t ImageAllocator::getSize (Context &context)
219 {
220         const DeviceInterface&  vk              = context.getDeviceInterface();
221         const VkDevice&                 device  = context.getDevice();
222         VkMemoryRequirements    memReq;
223
224         vk.getImageMemoryRequirements(device, *m_image, &memReq);
225
226         return (size_t)memReq.size;
227 }
228
229 class InvarianceInstance : public vkt::TestInstance
230 {
231 public:
232                                                         InvarianceInstance                      (Context&               context,
233                                                                                                                  const deUint32 seed);
234         virtual                                 ~InvarianceInstance                     (void);
235         virtual tcu::TestStatus iterate                                         (void);
236 private:
237         deRandom        m_random;
238 };
239
240 InvarianceInstance::InvarianceInstance  (Context&               context,
241                                                                                  const deUint32 seed)
242         : vkt::TestInstance     (context)
243 {
244         deRandom_init(&m_random, seed);
245 }
246
247 InvarianceInstance::~InvarianceInstance (void)
248 {
249 }
250
251 tcu::TestStatus InvarianceInstance::iterate (void)
252 {
253         de::MovePtr<IObjectAllocator>                   objs[testCycles];
254         size_t                                                                  refSizes[testCycles];
255         unsigned int                                                    order[testCycles];
256         bool                                                                    success                                                 = true;
257         const std::vector<std::string>&                 extensions                                              = m_context.getDeviceExtensions();
258         const deBool                                                    isDedicatedAllocationSupported  =
259                 isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_dedicated_allocation");
260         const deBool                                                    isYcbcrSupported =
261                 isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_sampler_ycbcr_conversion");
262         std::vector<int>                                                optimalFormats;
263         std::vector<int>                                                linearFormats;
264         std::vector<int>                                                memoryTypes;
265         vk::VkPhysicalDeviceMemoryProperties    memProperties;
266
267         // List of all VkFormat enums
268         const unsigned int                                              formatlist[]                                    = {
269                 VK_FORMAT_UNDEFINED,
270                 VK_FORMAT_R4G4_UNORM_PACK8,
271                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
272                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
273                 VK_FORMAT_R5G6B5_UNORM_PACK16,
274                 VK_FORMAT_B5G6R5_UNORM_PACK16,
275                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
276                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
277                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
278                 VK_FORMAT_R8_UNORM,
279                 VK_FORMAT_R8_SNORM,
280                 VK_FORMAT_R8_USCALED,
281                 VK_FORMAT_R8_SSCALED,
282                 VK_FORMAT_R8_UINT,
283                 VK_FORMAT_R8_SINT,
284                 VK_FORMAT_R8_SRGB,
285                 VK_FORMAT_R8G8_UNORM,
286                 VK_FORMAT_R8G8_SNORM,
287                 VK_FORMAT_R8G8_USCALED,
288                 VK_FORMAT_R8G8_SSCALED,
289                 VK_FORMAT_R8G8_UINT,
290                 VK_FORMAT_R8G8_SINT,
291                 VK_FORMAT_R8G8_SRGB,
292                 VK_FORMAT_R8G8B8_UNORM,
293                 VK_FORMAT_R8G8B8_SNORM,
294                 VK_FORMAT_R8G8B8_USCALED,
295                 VK_FORMAT_R8G8B8_SSCALED,
296                 VK_FORMAT_R8G8B8_UINT,
297                 VK_FORMAT_R8G8B8_SINT,
298                 VK_FORMAT_R8G8B8_SRGB,
299                 VK_FORMAT_B8G8R8_UNORM,
300                 VK_FORMAT_B8G8R8_SNORM,
301                 VK_FORMAT_B8G8R8_USCALED,
302                 VK_FORMAT_B8G8R8_SSCALED,
303                 VK_FORMAT_B8G8R8_UINT,
304                 VK_FORMAT_B8G8R8_SINT,
305                 VK_FORMAT_B8G8R8_SRGB,
306                 VK_FORMAT_R8G8B8A8_UNORM,
307                 VK_FORMAT_R8G8B8A8_SNORM,
308                 VK_FORMAT_R8G8B8A8_USCALED,
309                 VK_FORMAT_R8G8B8A8_SSCALED,
310                 VK_FORMAT_R8G8B8A8_UINT,
311                 VK_FORMAT_R8G8B8A8_SINT,
312                 VK_FORMAT_R8G8B8A8_SRGB,
313                 VK_FORMAT_B8G8R8A8_UNORM,
314                 VK_FORMAT_B8G8R8A8_SNORM,
315                 VK_FORMAT_B8G8R8A8_USCALED,
316                 VK_FORMAT_B8G8R8A8_SSCALED,
317                 VK_FORMAT_B8G8R8A8_UINT,
318                 VK_FORMAT_B8G8R8A8_SINT,
319                 VK_FORMAT_B8G8R8A8_SRGB,
320                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
321                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
322                 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
323                 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
324                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
325                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
326                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
327                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
328                 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
329                 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
330                 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
331                 VK_FORMAT_A2R10G10B10_UINT_PACK32,
332                 VK_FORMAT_A2R10G10B10_SINT_PACK32,
333                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
334                 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
335                 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
336                 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
337                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
338                 VK_FORMAT_A2B10G10R10_SINT_PACK32,
339                 VK_FORMAT_R16_UNORM,
340                 VK_FORMAT_R16_SNORM,
341                 VK_FORMAT_R16_USCALED,
342                 VK_FORMAT_R16_SSCALED,
343                 VK_FORMAT_R16_UINT,
344                 VK_FORMAT_R16_SINT,
345                 VK_FORMAT_R16_SFLOAT,
346                 VK_FORMAT_R16G16_UNORM,
347                 VK_FORMAT_R16G16_SNORM,
348                 VK_FORMAT_R16G16_USCALED,
349                 VK_FORMAT_R16G16_SSCALED,
350                 VK_FORMAT_R16G16_UINT,
351                 VK_FORMAT_R16G16_SINT,
352                 VK_FORMAT_R16G16_SFLOAT,
353                 VK_FORMAT_R16G16B16_UNORM,
354                 VK_FORMAT_R16G16B16_SNORM,
355                 VK_FORMAT_R16G16B16_USCALED,
356                 VK_FORMAT_R16G16B16_SSCALED,
357                 VK_FORMAT_R16G16B16_UINT,
358                 VK_FORMAT_R16G16B16_SINT,
359                 VK_FORMAT_R16G16B16_SFLOAT,
360                 VK_FORMAT_R16G16B16A16_UNORM,
361                 VK_FORMAT_R16G16B16A16_SNORM,
362                 VK_FORMAT_R16G16B16A16_USCALED,
363                 VK_FORMAT_R16G16B16A16_SSCALED,
364                 VK_FORMAT_R16G16B16A16_UINT,
365                 VK_FORMAT_R16G16B16A16_SINT,
366                 VK_FORMAT_R16G16B16A16_SFLOAT,
367                 VK_FORMAT_R32_UINT,
368                 VK_FORMAT_R32_SINT,
369                 VK_FORMAT_R32_SFLOAT,
370                 VK_FORMAT_R32G32_UINT,
371                 VK_FORMAT_R32G32_SINT,
372                 VK_FORMAT_R32G32_SFLOAT,
373                 VK_FORMAT_R32G32B32_UINT,
374                 VK_FORMAT_R32G32B32_SINT,
375                 VK_FORMAT_R32G32B32_SFLOAT,
376                 VK_FORMAT_R32G32B32A32_UINT,
377                 VK_FORMAT_R32G32B32A32_SINT,
378                 VK_FORMAT_R32G32B32A32_SFLOAT,
379                 VK_FORMAT_R64_UINT,
380                 VK_FORMAT_R64_SINT,
381                 VK_FORMAT_R64_SFLOAT,
382                 VK_FORMAT_R64G64_UINT,
383                 VK_FORMAT_R64G64_SINT,
384                 VK_FORMAT_R64G64_SFLOAT,
385                 VK_FORMAT_R64G64B64_UINT,
386                 VK_FORMAT_R64G64B64_SINT,
387                 VK_FORMAT_R64G64B64_SFLOAT,
388                 VK_FORMAT_R64G64B64A64_UINT,
389                 VK_FORMAT_R64G64B64A64_SINT,
390                 VK_FORMAT_R64G64B64A64_SFLOAT,
391                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
392                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
393                 VK_FORMAT_D16_UNORM,
394                 VK_FORMAT_X8_D24_UNORM_PACK32,
395                 VK_FORMAT_D32_SFLOAT,
396                 VK_FORMAT_S8_UINT,
397                 VK_FORMAT_D16_UNORM_S8_UINT,
398                 VK_FORMAT_D24_UNORM_S8_UINT,
399                 VK_FORMAT_D32_SFLOAT_S8_UINT,
400                 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
401                 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
402                 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
403                 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
404                 VK_FORMAT_BC2_UNORM_BLOCK,
405                 VK_FORMAT_BC2_SRGB_BLOCK,
406                 VK_FORMAT_BC3_UNORM_BLOCK,
407                 VK_FORMAT_BC3_SRGB_BLOCK,
408                 VK_FORMAT_BC4_UNORM_BLOCK,
409                 VK_FORMAT_BC4_SNORM_BLOCK,
410                 VK_FORMAT_BC5_UNORM_BLOCK,
411                 VK_FORMAT_BC5_SNORM_BLOCK,
412                 VK_FORMAT_BC6H_UFLOAT_BLOCK,
413                 VK_FORMAT_BC6H_SFLOAT_BLOCK,
414                 VK_FORMAT_BC7_UNORM_BLOCK,
415                 VK_FORMAT_BC7_SRGB_BLOCK,
416                 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
417                 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
418                 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
419                 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
420                 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
421                 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
422                 VK_FORMAT_EAC_R11_UNORM_BLOCK,
423                 VK_FORMAT_EAC_R11_SNORM_BLOCK,
424                 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
425                 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
426                 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
427                 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
428                 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
429                 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
430                 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
431                 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
432                 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
433                 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
434                 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
435                 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
436                 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
437                 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
438                 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
439                 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
440                 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
441                 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
442                 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
443                 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
444                 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
445                 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
446                 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
447                 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
448                 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
449                 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
450                 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
451                 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
452                 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
453                 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
454                 VK_FORMAT_G8B8G8R8_422_UNORM,
455                 VK_FORMAT_B8G8R8G8_422_UNORM,
456                 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
457                 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
458                 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
459                 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
460                 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
461                 VK_FORMAT_R10X6_UNORM_PACK16,
462                 VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
463                 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
464                 VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
465                 VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
466                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
467                 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
468                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
469                 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
470                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
471                 VK_FORMAT_R12X4_UNORM_PACK16,
472                 VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
473                 VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
474                 VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
475                 VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
476                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
477                 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
478                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
479                 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
480                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
481                 VK_FORMAT_G16B16G16R16_422_UNORM,
482                 VK_FORMAT_B16G16R16G16_422_UNORM,
483                 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
484                 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
485                 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
486                 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
487                 VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
488                 VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG,
489                 VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG,
490                 VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG,
491                 VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG,
492                 VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG,
493                 VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG,
494                 VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG,
495                 VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG
496         };
497         int                                                                             formatCount                                             = (int)(sizeof(formatlist) / sizeof(unsigned int));
498
499         // If ycbcr is not supported, only use the standard texture formats
500         if (!isYcbcrSupported)
501                 formatCount = 184;
502
503         // Find supported image formats
504         for (int i = 0; i < formatCount; i++)
505         {
506                 vk::VkImageFormatProperties imageformatprops;
507
508                 // Check for support in linear tiling mode
509                 if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
510                         m_context.getPhysicalDevice(),
511                         (VkFormat)formatlist[i],
512                         VK_IMAGE_TYPE_2D,
513                         VK_IMAGE_TILING_LINEAR,
514                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
515                         0,
516                         &imageformatprops) == VK_SUCCESS)
517                         linearFormats.push_back(formatlist[i]);
518
519                 // Check for support in optimal tiling mode
520                 if (m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
521                         m_context.getPhysicalDevice(),
522                         (VkFormat)formatlist[i],
523                         VK_IMAGE_TYPE_2D,
524                         VK_IMAGE_TILING_OPTIMAL,
525                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
526                         0,
527                         &imageformatprops) == VK_SUCCESS)
528                         optimalFormats.push_back(formatlist[i]);
529         }
530
531         // Check for supported heap types
532         m_context.getInstanceInterface().getPhysicalDeviceMemoryProperties(m_context.getPhysicalDevice(), &memProperties);
533
534         for (unsigned int j = 0; j < legalMemoryTypeCount; j++)
535         {
536                 bool found = false;
537                 for (unsigned int i = 0; !found && i < memProperties.memoryTypeCount; i++)
538                 {
539                         if (legalMemoryTypes[j].matchesHeap(memProperties.memoryTypes[i].propertyFlags))
540                         {
541                                 memoryTypes.push_back(j);
542                                 found = true;
543                         }
544                 }
545         }
546
547         // Log the used image types and heap types
548         tcu::TestLog& log = m_context.getTestContext().getLog();
549
550         {
551                 std::ostringstream values;
552                 for (unsigned int i = 0; i < linearFormats.size(); i++)
553                         values << " " << linearFormats[i];
554                 log << tcu::TestLog::Message << "Using linear formats:" << values.str() << tcu::TestLog::EndMessage;
555         }
556
557         {
558                 std::ostringstream values;
559                 for (unsigned int i = 0; i < optimalFormats.size(); i++)
560                         values << " " << optimalFormats[i];
561                 log << tcu::TestLog::Message << "Using optimal formats:" << values.str() << tcu::TestLog::EndMessage;
562         }
563
564         {
565                 std::ostringstream values;
566                 for (unsigned int i = 0; i < memoryTypes.size(); i++)
567                         values << " " << memoryTypes[i];
568                 log << tcu::TestLog::Message << "Using memory types:" << values.str() << tcu::TestLog::EndMessage;
569         }
570
571         for (unsigned int i = 0; i < testCycles; i++)
572         {
573                 if (deRandom_getBool(&m_random))
574                         objs[i] = de::MovePtr<IObjectAllocator>(new BufferAllocator(m_random, isDedicatedAllocationSupported, memoryTypes));
575                 else
576                         objs[i] = de::MovePtr<IObjectAllocator>(new ImageAllocator(m_random, isDedicatedAllocationSupported, linearFormats, optimalFormats, memoryTypes));
577                 order[i] = i;
578         }
579
580         // First get reference values for the object sizes
581         for (unsigned int i = 0; i < testCycles; i++)
582         {
583                 objs[i]->allocate(m_context);
584                 refSizes[i] = objs[i]->getSize(m_context);
585                 objs[i]->deallocate(m_context);
586         }
587
588         // Shuffle order by swapping random pairs
589         for (unsigned int i = 0; i < testCycles; i++)
590         {
591                 int a = deRandom_getUint32(&m_random) % testCycles;
592                 int b = deRandom_getUint32(&m_random) % testCycles;
593                 DE_SWAP(int, order[a], order[b]);
594         }
595
596         // Allocate objects in shuffled order
597         for (unsigned int i = 0; i < testCycles; i++)
598                 objs[order[i]]->allocate(m_context);
599
600         // Check for size mismatches
601         for (unsigned int i = 0; i < testCycles; i++)
602         {
603                 size_t val = objs[order[i]]->getSize(m_context);
604
605                 if (val != refSizes[order[i]])
606                 {
607                         success = false;
608                         log     << tcu::TestLog::Message
609                                 << "Object "
610                                 << order[i]
611                                 << " size mismatch ("
612                                 << val
613                                 << " != "
614                                 << refSizes[order[i]]
615                                 << ")"
616                                 << tcu::TestLog::EndMessage;
617                 }
618         }
619
620         // Clean up
621         for (unsigned int i = 0; i < testCycles; i++)
622                 objs[order[i]]->deallocate(m_context);
623
624         if (success)
625                 return tcu::TestStatus::pass("Pass");
626
627         return tcu::TestStatus::fail("One or more allocation is not invariant");
628 }
629
630 class InvarianceCase : public vkt::TestCase
631 {
632 public:
633                                                         InvarianceCase  (tcu::TestContext&      testCtx,
634                                                                                          const std::string&     name,
635                                                                                          const std::string&     description);
636         virtual                                 ~InvarianceCase (void);
637
638         virtual TestInstance*   createInstance  (Context&                       context) const;
639 };
640
641 InvarianceCase::InvarianceCase  (tcu::TestContext&      testCtx,
642                                                                  const std::string&     name,
643                                                                  const std::string&     description)
644         : vkt::TestCase(testCtx, name, description)
645 {
646 }
647
648 InvarianceCase::~InvarianceCase()
649 {
650 }
651
652 TestInstance* InvarianceCase::createInstance (Context& context) const
653 {
654         return new InvarianceInstance(context, 0x600613);
655 }
656
657 tcu::TestCaseGroup* createMemoryRequirementInvarianceTests (tcu::TestContext& testCtx)
658 {
659         de::MovePtr<tcu::TestCaseGroup> invarianceTests(new tcu::TestCaseGroup(testCtx, "invariance", "Memory requirement invariance tests"));
660
661         // Only one child, leaving room for potential targeted cases later on.
662         invarianceTests->addChild(new InvarianceCase(testCtx, "random", std::string("Random case")));
663
664         return invarianceTests.release();
665 }
666
667 } // api
668 } // vkt