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