Do not use ycbcr formats if ycbcr extension is not supported
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / memory / vktMemoryRequirementsTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Buffer and image memory requirements tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktMemoryRequirementsTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktTestGroupUtil.hpp"
27
28 #include "vkDefs.hpp"
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkStrUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkImageUtil.hpp"
36
37 #include "deUniquePtr.hpp"
38 #include "deStringUtil.hpp"
39 #include "deSTLUtil.hpp"
40
41 #include "tcuResultCollector.hpp"
42 #include "tcuTestLog.hpp"
43
44 namespace vkt
45 {
46 namespace memory
47 {
48 namespace
49 {
50 using namespace vk;
51 using de::MovePtr;
52 using tcu::TestLog;
53
54 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
55 {
56         const VkBufferCreateInfo createInfo =
57         {
58                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType        sType;
59                 DE_NULL,                                                                        // const void*            pNext;
60                 flags,                                                                          // VkBufferCreateFlags    flags;
61                 size,                                                                           // VkDeviceSize           size;
62                 usage,                                                                          // VkBufferUsageFlags     usage;
63                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode          sharingMode;
64                 0u,                                                                                     // uint32_t               queueFamilyIndexCount;
65                 DE_NULL,                                                                        // const uint32_t*        pQueueFamilyIndices;
66         };
67         return createBuffer(vk, device, &createInfo);
68 }
69
70 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
71 {
72         const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
73         return getBufferMemoryRequirements(vk, device, *buffer);
74 }
75
76 VkMemoryRequirements getBufferMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL)
77 {
78         const Unique<VkBuffer>                          buffer          (makeBuffer(vk, device, size, flags, usage));
79         VkBufferMemoryRequirementsInfo2KHR      info    =
80         {
81                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,        // VkStructureType      sType
82                 DE_NULL,                                                                                                        // const void*          pNext
83                 *buffer                                                                                                         // VkBuffer                     buffer
84         };
85         VkMemoryRequirements2KHR                        req2    =
86         {
87                 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,                            // VkStructureType              sType
88                 next,                                                                                                           // void*                                pNext
89                 {0, 0, 0}                                                                                                       // VkMemoryRequirements memoryRequirements
90         };
91
92         vk.getBufferMemoryRequirements2KHR(device, &info, &req2);
93
94         return req2.memoryRequirements;
95 }
96
97 VkMemoryRequirements getImageMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL)
98 {
99         const Unique<VkImage> image(createImage(vk, device, &createInfo));
100
101         VkImageMemoryRequirementsInfo2KHR       info    =
102         {
103                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,         // VkStructureType      sType
104                 DE_NULL,                                                                                                        // const void*          pNext
105                 *image                                                                                                          // VkImage                      image
106         };
107         VkMemoryRequirements2KHR                        req2    =
108         {
109                 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,                            // VkStructureType              sType
110                 next,                                                                                                           // void*                                pNext
111                 {0, 0, 0}                                                                                                       // VkMemoryRequirements memoryRequirements
112         };
113
114         vk.getImageMemoryRequirements2KHR(device, &info, &req2);
115
116         return req2.memoryRequirements;
117 }
118
119 //! Get an index of each set bit, starting from the least significant bit.
120 std::vector<deUint32> bitsToIndices (deUint32 bits)
121 {
122         std::vector<deUint32> indices;
123         for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1)
124         {
125                 if (bits & 1u)
126                         indices.push_back(i);
127         }
128         return indices;
129 }
130
131 template<typename T>
132 T nextEnum (T value)
133 {
134         return static_cast<T>(static_cast<deUint32>(value) + 1);
135 }
136
137 template<typename T>
138 T nextFlag (T value)
139 {
140         if (value)
141                 return static_cast<T>(static_cast<deUint32>(value) << 1);
142         else
143                 return static_cast<T>(1);
144 }
145
146 template<typename T>
147 T nextFlagExcluding (T value, T excludedFlags)
148 {
149         deUint32 tmp = static_cast<deUint32>(value);
150         while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags));
151         return static_cast<T>(tmp);
152 }
153
154 bool validValueVkBool32 (const VkBool32 value)
155 {
156         return (value == VK_FALSE || value == VK_TRUE);
157 }
158
159 class IBufferMemoryRequirements
160 {
161 public:
162         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group) = 0;
163
164 protected:
165         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
166                                                                                          const std::string&                                                     name,
167                                                                                          const std::string&                                                     desc,
168                                                                                          VkBufferCreateFlags                                            arg0) = 0;
169
170         virtual tcu::TestStatus execTest                (Context&                                                                       context,
171                                                                                          const VkBufferCreateFlags                                      bufferFlags) = 0;
172
173         virtual void preTestChecks                              (Context&                                                                       context,
174                                                                                          const InstanceInterface&                                       vki,
175                                                                                          const VkPhysicalDevice                                         physDevice,
176                                                                                          const VkBufferCreateFlags                                      flags) = 0;
177
178         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
179                                                                                          const VkDevice                                                         device,
180                                                                                          const VkDeviceSize                                                     size,
181                                                                                          const VkBufferCreateFlags                                      flags,
182                                                                                          const VkBufferUsageFlags                                       usage,
183                                                                                          const bool                                                                     all) = 0;
184
185         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
186                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
187                                                                                          const VkPhysicalDeviceLimits&                          limits,
188                                                                                          const VkBufferCreateFlags                                      bufferFlags,
189                                                                                          const VkBufferUsageFlags                                       usage) = 0;
190 };
191
192 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
193 {
194         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
195                                                                                          const VkBufferCreateFlags                                      bufferFlags);
196
197 public:
198         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group);
199
200 protected:
201         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
202                                                                                          const std::string&                                                     name,
203                                                                                          const std::string&                                                     desc,
204                                                                                          VkBufferCreateFlags                                            arg0);
205
206         virtual tcu::TestStatus execTest                (Context&                                                                       context,
207                                                                                          const VkBufferCreateFlags                                      bufferFlags);
208
209         virtual void preTestChecks                              (Context&                                                                       context,
210                                                                                          const InstanceInterface&                                       vki,
211                                                                                          const VkPhysicalDevice                                         physDevice,
212                                                                                          const VkBufferCreateFlags                                      flags);
213
214         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
215                                                                                          const VkDevice                                                         device,
216                                                                                          const VkDeviceSize                                                     size,
217                                                                                          const VkBufferCreateFlags                                      flags,
218                                                                                          const VkBufferUsageFlags                                       usage,
219                                                                                          const bool                                                                     all);
220
221         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
222                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
223                                                                                          const VkPhysicalDeviceLimits&                          limits,
224                                                                                          const VkBufferCreateFlags                                      bufferFlags,
225                                                                                          const VkBufferUsageFlags                                       usage);
226
227 protected:
228         VkMemoryRequirements    m_allUsageFlagsRequirements;
229         VkMemoryRequirements    m_currentTestRequirements;
230 };
231
232
233 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
234 {
235         BufferMemoryRequirementsOriginal test;
236
237         return test.execTest(context, bufferFlags);
238 }
239
240 void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
241 {
242         const struct
243         {
244                 VkBufferCreateFlags             flags;
245                 const char* const               name;
246         } bufferCases[] =
247         {
248                 { (VkBufferCreateFlags)0,                                                                                                                                                                                               "regular"                                       },
249                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                  "sparse"                                        },
250                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,                                                                                  "sparse_residency"                      },
251                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT                                                                                   | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,  "sparse_aliased"                        },
252                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT   | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,  "sparse_residency_aliased"      },
253         };
254
255         de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", ""));
256
257         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
258                 addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, "", bufferCases[ndx].flags);
259
260         group->addChild(bufferGroup.release());
261 }
262
263 void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group,
264                                                                                                                         const std::string&      name,
265                                                                                                                         const std::string&      desc,
266                                                                                                                         VkBufferCreateFlags     arg0)
267 {
268         addFunctionCase(group, name, desc, testEntryPoint, arg0);
269 }
270
271 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags)
272 {
273         const DeviceInterface&                                  vk                      = context.getDeviceInterface();
274         const InstanceInterface&                                vki                     = context.getInstanceInterface();
275         const VkDevice                                                  device          = context.getDevice();
276         const VkPhysicalDevice                                  physDevice      = context.getPhysicalDevice();
277
278         preTestChecks(context, vki, physDevice, bufferFlags);
279
280         const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vki, physDevice);
281         const VkPhysicalDeviceLimits                    limits                          = getPhysicalDeviceProperties(vki, physDevice).limits;
282         const VkBufferUsageFlags                                allUsageFlags           = static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
283         tcu::TestLog&                                                   log                                     = context.getTestContext().getLog();
284         bool                                                                    allPass                         = true;
285
286         const VkDeviceSize sizeCases[] =
287         {
288                 1    * 1024,
289                 8    * 1024,
290                 64   * 1024,
291                 1024 * 1024,
292         };
293
294         // Updates m_allUsageFlags* fields
295         updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
296
297         for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
298         {
299                 deUint32                previousMemoryTypeBits  = 0u;
300                 VkDeviceSize    previousAlignment               = 0u;
301
302                 log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;
303
304                 for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
305                 {
306                         log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
307
308                         tcu::ResultCollector result(log, "ERROR: ");
309
310                         // Updates m_allUsageFlags* fields
311                         updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
312
313                         // Check:
314                         // - requirements for a particular buffer usage
315                         // - memoryTypeBits are a subset of bits for requirements with all usage flags combined
316                         verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
317
318                         // Check that for the same usage and create flags:
319                         // - memoryTypeBits are the same
320                         // - alignment is the same
321                         if (pSize > sizeCases)
322                         {
323                                 result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
324                                         "memoryTypeBits differ from the ones in the previous buffer size");
325
326                                 result.check(m_currentTestRequirements.alignment == previousAlignment,
327                                         "alignment differs from the one in the previous buffer size");
328                         }
329
330                         if (result.getResult() != QP_TEST_RESULT_PASS)
331                                 allPass = false;
332
333                         previousMemoryTypeBits  = m_currentTestRequirements.memoryTypeBits;
334                         previousAlignment               = m_currentTestRequirements.alignment;
335                 }
336
337                 if (!allPass)
338                         break;
339         }
340
341         return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
342 }
343
344 void BufferMemoryRequirementsOriginal::preTestChecks (Context&                                                          ,
345                                                                                                           const InstanceInterface&                              vki,
346                                                                                                           const VkPhysicalDevice                                physDevice,
347                                                                                                           const VkBufferCreateFlags                             flags)
348 {
349         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
350
351         if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
352                 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
353
354         if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer)
355                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer");
356
357         if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
358                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
359 }
360
361 void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface&         vk,
362                                                                                                                                  const VkDevice                         device,
363                                                                                                                                  const VkDeviceSize                     size,
364                                                                                                                                  const VkBufferCreateFlags      flags,
365                                                                                                                                  const VkBufferUsageFlags       usage,
366                                                                                                                                  const bool                                     all)
367 {
368         if (all)
369         {
370                 m_allUsageFlagsRequirements     = getBufferMemoryRequirements(vk, device, size, flags, usage);
371         }
372         else
373         {
374                 m_currentTestRequirements       = getBufferMemoryRequirements(vk, device, size, flags, usage);
375         }
376 }
377
378 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&                                          result,
379                                                                                                                                  const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
380                                                                                                                                  const VkPhysicalDeviceLimits&                          limits,
381                                                                                                                                  const VkBufferCreateFlags                                      bufferFlags,
382                                                                                                                                  const VkBufferUsageFlags                                       usage)
383 {
384         if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
385         {
386                 typedef std::vector<deUint32>::const_iterator   IndexIterator;
387                 const std::vector<deUint32>                                             usedMemoryTypeIndices                   = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
388                 bool                                                                                    deviceLocalMemoryFound                  = false;
389                 bool                                                                                    hostVisibleCoherentMemoryFound  = false;
390
391                 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
392                 {
393                         if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
394                         {
395                                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
396                                 continue;
397                         }
398
399                         const VkMemoryPropertyFlags     memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
400
401                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
402                                 deviceLocalMemoryFound = true;
403
404                         if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
405                                 hostVisibleCoherentMemoryFound = true;
406
407                         result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
408                                 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
409                 }
410
411                 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
412                         "VkMemoryRequirements alignment isn't power of two");
413
414                 if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
415                 {
416                         result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
417                                 "VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
418                 }
419
420                 if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
421                 {
422                         result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
423                                 "VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
424                 }
425
426                 if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
427                 {
428                         result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
429                                 "VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
430                 }
431
432                 result.check(deviceLocalMemoryFound,
433                         "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
434
435                 result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
436                         "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
437
438                 result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits,
439                         "Memory type bits aren't a superset of memory type bits for all usage flags combined");
440         }
441 }
442
443 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
444 {
445         static tcu::TestStatus testEntryPoint   (Context&                                       context,
446                                                                                          const VkBufferCreateFlags      bufferFlags);
447
448 protected:
449         virtual void addFunctionTestCase                (tcu::TestCaseGroup*            group,
450                                                                                          const std::string&                     name,
451                                                                                          const std::string&                     desc,
452                                                                                          VkBufferCreateFlags            arg0);
453
454         virtual void preTestChecks                              (Context&                                       context,
455                                                                                          const InstanceInterface&       vki,
456                                                                                          const VkPhysicalDevice         physDevice,
457                                                                                          const VkBufferCreateFlags      flags);
458
459         virtual void updateMemoryRequirements   (const DeviceInterface&         vk,
460                                                                                          const VkDevice                         device,
461                                                                                          const VkDeviceSize                     size,
462                                                                                          const VkBufferCreateFlags      flags,
463                                                                                          const VkBufferUsageFlags       usage,
464                                                                                          const bool                                     all);
465 };
466
467 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
468 {
469         BufferMemoryRequirementsExtended test;
470
471         return test.execTest(context, bufferFlags);
472 }
473
474 void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group,
475                                                                                                                         const std::string&      name,
476                                                                                                                         const std::string&      desc,
477                                                                                                                         VkBufferCreateFlags     arg0)
478 {
479         addFunctionCase(group, name, desc, testEntryPoint, arg0);
480 }
481
482 void BufferMemoryRequirementsExtended::preTestChecks (Context&                                  context,
483                                                                                                           const InstanceInterface&      vki,
484                                                                                                           const VkPhysicalDevice        physDevice,
485                                                                                                           const VkBufferCreateFlags     flags)
486 {
487         const std::string extensionName("VK_KHR_get_memory_requirements2");
488
489         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
490                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
491
492         BufferMemoryRequirementsOriginal::preTestChecks(context, vki, physDevice, flags);
493 }
494
495 void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&         vk,
496                                                                                                                                  const VkDevice                         device,
497                                                                                                                                  const VkDeviceSize                     size,
498                                                                                                                                  const VkBufferCreateFlags      flags,
499                                                                                                                                  const VkBufferUsageFlags       usage,
500                                                                                                                                  const bool                                     all)
501 {
502         if (all)
503         {
504                 m_allUsageFlagsRequirements     = getBufferMemoryRequirements2(vk, device, size, flags, usage);
505         }
506         else
507         {
508                 m_currentTestRequirements       = getBufferMemoryRequirements2(vk, device, size, flags, usage);
509         }
510 }
511
512
513 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
514 {
515         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
516                                                                                          const VkBufferCreateFlags                                      bufferFlags);
517
518 protected:
519         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
520                                                                                          const std::string&                                                     name,
521                                                                                          const std::string&                                                     desc,
522                                                                                          VkBufferCreateFlags                                            arg0);
523
524         virtual void preTestChecks                              (Context&                                                                       context,
525                                                                                          const InstanceInterface&                                       vki,
526                                                                                          const VkPhysicalDevice                                         physDevice,
527                                                                                          const VkBufferCreateFlags                                      flags);
528
529         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
530                                                                                          const VkDevice                                                         device,
531                                                                                          const VkDeviceSize                                                     size,
532                                                                                          const VkBufferCreateFlags                                      flags,
533                                                                                          const VkBufferUsageFlags                                       usage,
534                                                                                          const bool                                                                     all);
535
536         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
537                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
538                                                                                          const VkPhysicalDeviceLimits&                          limits,
539                                                                                          const VkBufferCreateFlags                                      bufferFlags,
540                                                                                          const VkBufferUsageFlags                                       usage);
541
542 protected:
543         VkBool32        m_allUsageFlagsPrefersDedicatedAllocation;
544         VkBool32        m_allUsageFlagsRequiresDedicatedAllocation;
545
546         VkBool32        m_currentTestPrefersDedicatedAllocation;
547         VkBool32        m_currentTestRequiresDedicatedAllocation;
548 };
549
550
551 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
552 {
553         BufferMemoryRequirementsDedicatedAllocation test;
554
555         return test.execTest(context, bufferFlags);
556 }
557
558 void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*      group,
559                                                                                                                                            const std::string&   name,
560                                                                                                                                            const std::string&   desc,
561                                                                                                                                            VkBufferCreateFlags  arg0)
562 {
563         addFunctionCase(group, name, desc, testEntryPoint, arg0);
564 }
565
566 void BufferMemoryRequirementsDedicatedAllocation::preTestChecks (Context&                                       context,
567                                                                                                                                  const InstanceInterface&       vki,
568                                                                                                                                  const VkPhysicalDevice         physDevice,
569                                                                                                                                  const VkBufferCreateFlags      flags)
570 {
571         const std::string extensionName("VK_KHR_dedicated_allocation");
572
573         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
574                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
575
576         BufferMemoryRequirementsExtended::preTestChecks(context, vki, physDevice, flags);
577 }
578
579 void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&              vk,
580                                                                                                                                                         const VkDevice                          device,
581                                                                                                                                                         const VkDeviceSize                      size,
582                                                                                                                                                         const VkBufferCreateFlags       flags,
583                                                                                                                                                         const VkBufferUsageFlags        usage,
584                                                                                                                                                         const bool                                      all)
585 {
586         const deUint32                                          invalidVkBool32                 = static_cast<deUint32>(~0);
587
588         VkMemoryDedicatedRequirementsKHR        dedicatedRequirements   =
589         {
590                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,    // VkStructureType      sType
591                 DE_NULL,                                                                                                // void*                        pNext
592                 invalidVkBool32,                                                                                // VkBool32                     prefersDedicatedAllocation
593                 invalidVkBool32                                                                                 // VkBool32                     requiresDedicatedAllocation
594         };
595
596         if (all)
597         {
598                 m_allUsageFlagsRequirements                                     = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
599                 m_allUsageFlagsPrefersDedicatedAllocation       = dedicatedRequirements.prefersDedicatedAllocation;
600                 m_allUsageFlagsRequiresDedicatedAllocation      = dedicatedRequirements.requiresDedicatedAllocation;
601
602                 TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation));
603                 // Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false
604                 TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE);
605         }
606         else
607         {
608                 m_currentTestRequirements                                       = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
609                 m_currentTestPrefersDedicatedAllocation         = dedicatedRequirements.prefersDedicatedAllocation;
610                 m_currentTestRequiresDedicatedAllocation        = dedicatedRequirements.requiresDedicatedAllocation;
611         }
612 }
613
614 void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&                                       result,
615                                                                                                                                                         const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
616                                                                                                                                                         const VkPhysicalDeviceLimits&                   limits,
617                                                                                                                                                         const VkBufferCreateFlags                               bufferFlags,
618                                                                                                                                                         const VkBufferUsageFlags                                usage)
619 {
620         BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage);
621
622         result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
623                 "Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation");
624
625         result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
626                 "Regular (non-shared) objects must not require dedicated allocations");
627
628         result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
629                 "Preferred and required flags for dedicated memory cannot be set to true at the same time");
630 }
631
632
633 struct ImageTestParams
634 {
635         ImageTestParams (VkImageCreateFlags             flags_,
636                                          VkImageTiling                  tiling_,
637                                          bool                                   transient_)
638         : flags         (flags_)
639         , tiling        (tiling_)
640         , transient     (transient_)
641         {
642         }
643
644         ImageTestParams (void)
645         {
646         }
647
648         VkImageCreateFlags              flags;
649         VkImageTiling                   tiling;
650         bool                                    transient;
651 };
652
653 class IImageMemoryRequirements
654 {
655 public:
656         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group) = 0;
657
658 protected:
659         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
660                                                                                          const std::string&                                                     name,
661                                                                                          const std::string&                                                     desc,
662                                                                                          const ImageTestParams                                          arg0) = 0;
663
664         virtual tcu::TestStatus execTest                (Context&                                                                       context,
665                                                                                          const ImageTestParams                                          bufferFlags) = 0;
666
667         virtual void preTestChecks                              (Context&                                                                       context,
668                                                                                          const InstanceInterface&                                       vki,
669                                                                                          const VkPhysicalDevice                                         physDevice,
670                                                                                          const VkImageCreateFlags                                       flags) = 0;
671
672         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
673                                                                                          const VkDevice                                                         device) = 0;
674
675         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
676                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties) = 0;
677 };
678
679 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
680 {
681         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
682                                                                                          const ImageTestParams                                          params);
683
684 public:
685         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group);
686
687 protected:
688         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
689                                                                                          const std::string&                                                     name,
690                                                                                          const std::string&                                                     desc,
691                                                                                          const ImageTestParams                                          arg0);
692
693         virtual tcu::TestStatus execTest                (Context&                                                                       context,
694                                                                                          const ImageTestParams                                          params);
695
696         virtual void preTestChecks                              (Context&                                                                       context,
697                                                                                          const InstanceInterface&                                       vki,
698                                                                                          const VkPhysicalDevice                                         physDevice,
699                                                                                          const VkImageCreateFlags                                       flags);
700
701         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
702                                                                                          const VkDevice                                                         device);
703
704         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
705                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties);
706
707 private:
708         virtual bool isImageSupported                   (const InstanceInterface&                                       vki,
709                                                                                          const VkPhysicalDevice                                         physDevice,
710                                                                                          const std::vector<std::string>&                        deviceExtensions,
711                                                                                          const VkImageCreateInfo&                                       info);
712
713         virtual bool isFormatMatchingAspect             (const VkFormat                                                         format,
714                                                                                          const VkImageAspectFlags                                       aspect);
715
716 protected:
717         VkImageCreateInfo               m_currentTestImageInfo;
718         VkMemoryRequirements    m_currentTestRequirements;
719 };
720
721
722 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
723 {
724         ImageMemoryRequirementsOriginal test;
725
726         return test.execTest(context, params);
727 }
728
729 void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
730 {
731         const struct
732         {
733                 VkImageCreateFlags              flags;
734                 bool                                    transient;
735                 const char* const               name;
736         } imageFlagsCases[] =
737         {
738                 { (VkImageCreateFlags)0,                                                                                                                                                                                                false,  "regular"                                       },
739                 { (VkImageCreateFlags)0,                                                                                                                                                                                                true,   "transient"                                     },
740                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                   false,  "sparse"                                        },
741                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,                                                                                    false,  "sparse_residency"                      },
742                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT                                                                                    | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_aliased"                        },
743                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT             | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_residency_aliased"      },
744         };
745
746         de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", ""));
747
748         for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
749         for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
750         {
751                 ImageTestParams         params;
752                 std::ostringstream      caseName;
753
754                 params.flags            =  imageFlagsCases[flagsNdx].flags;
755                 params.transient        =  imageFlagsCases[flagsNdx].transient;
756                 caseName                        << imageFlagsCases[flagsNdx].name;
757
758                 if (tilingNdx != 0)
759                 {
760                         params.tiling =  VK_IMAGE_TILING_OPTIMAL;
761                         caseName      << "_tiling_optimal";
762                 }
763                 else
764                 {
765                         params.tiling =  VK_IMAGE_TILING_LINEAR;
766                         caseName      << "_tiling_linear";
767                 }
768
769                 if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
770                         continue;
771
772                 addFunctionTestCase(imageGroup.get(), caseName.str(), "", params);
773         }
774
775         group->addChild(imageGroup.release());
776 }
777
778 void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*          group,
779                                                                                                                    const std::string&           name,
780                                                                                                                    const std::string&           desc,
781                                                                                                                    const ImageTestParams        arg0)
782 {
783         addFunctionCase(group, name, desc, testEntryPoint, arg0);
784 }
785
786 void ImageMemoryRequirementsOriginal::preTestChecks (Context&                                   ,
787                                                                                                          const InstanceInterface&       vki,
788                                                                                                          const VkPhysicalDevice         physDevice,
789                                                                                                          const VkImageCreateFlags       createFlags)
790 {
791         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
792
793         if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
794                 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
795
796         if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
797                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
798
799         if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
800                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
801 }
802
803 void ImageMemoryRequirementsOriginal::updateMemoryRequirements  (const DeviceInterface&         vk,
804                                                                                                                                  const VkDevice                         device)
805 {
806         const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
807
808         m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
809 }
810
811 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&                                   result,
812                                                                                                                                 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties)
813 {
814         if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
815         {
816                 typedef std::vector<deUint32>::const_iterator   IndexIterator;
817                 const std::vector<deUint32>                                             usedMemoryTypeIndices                   = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
818                 bool                                                                                    deviceLocalMemoryFound                  = false;
819                 bool                                                                                    hostVisibleCoherentMemoryFound  = false;
820
821                 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
822                 {
823                         if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
824                         {
825                                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
826                                 continue;
827                         }
828
829                         const VkMemoryPropertyFlags     memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
830
831                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
832                                 deviceLocalMemoryFound = true;
833
834                         if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
835                                 hostVisibleCoherentMemoryFound = true;
836
837                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
838                         {
839                                 result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
840                                         "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
841                         }
842                 }
843
844                 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
845                         "VkMemoryRequirements alignment isn't power of two");
846
847                 result.check(deviceLocalMemoryFound,
848                         "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
849
850                 result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
851                         "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
852         }
853 }
854
855 bool isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
856 {
857         if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
858                 return true;
859         if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
860                 return true;
861         if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
862                 return true;
863         if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
864                 return true;
865
866         return false;
867 }
868
869 //! This catches both invalid as well as legal but unsupported combinations of image parameters
870 bool ImageMemoryRequirementsOriginal::isImageSupported (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const std::vector<std::string>& deviceExtensions, const VkImageCreateInfo& info)
871 {
872         DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
873
874         if ((isYCbCrFormat(info.format)
875                 && (info.imageType != VK_IMAGE_TYPE_2D
876                         || info.mipLevels != 1
877                         || info.arrayLayers != 1
878                         || info.samples != VK_SAMPLE_COUNT_1_BIT))
879                         || !de::contains(deviceExtensions.begin(), deviceExtensions.end(), "VK_KHR_sampler_ycbcr_conversion"))
880         {
881                 return false;
882         }
883
884         if (info.imageType == VK_IMAGE_TYPE_1D)
885         {
886                 DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
887         }
888         else if (info.imageType == VK_IMAGE_TYPE_2D)
889         {
890                 DE_ASSERT(info.extent.depth == 1u);
891
892                 if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
893                 {
894                         DE_ASSERT(info.extent.width == info.extent.height);
895                         DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
896                 }
897         }
898
899         if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
900                 return false;
901
902         if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
903                 (info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
904                 return false;
905
906         if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
907                 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
908                 return false;
909
910         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
911
912         if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
913         {
914                 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
915
916                 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
917                         return false;
918                 if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
919                         return false;
920                 if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
921                         return false;
922                 if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
923                         return false;
924                 if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
925                         return false;
926                 if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
927                         return false;
928                 if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
929                         return false;
930         }
931
932         if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
933                 return false;
934
935         switch (info.format)
936         {
937                 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
938                 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
939                 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
940                 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
941                 case VK_FORMAT_BC2_UNORM_BLOCK:
942                 case VK_FORMAT_BC2_SRGB_BLOCK:
943                 case VK_FORMAT_BC3_UNORM_BLOCK:
944                 case VK_FORMAT_BC3_SRGB_BLOCK:
945                 case VK_FORMAT_BC4_UNORM_BLOCK:
946                 case VK_FORMAT_BC4_SNORM_BLOCK:
947                 case VK_FORMAT_BC5_UNORM_BLOCK:
948                 case VK_FORMAT_BC5_SNORM_BLOCK:
949                 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
950                 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
951                 case VK_FORMAT_BC7_UNORM_BLOCK:
952                 case VK_FORMAT_BC7_SRGB_BLOCK:
953                         if (!features.textureCompressionBC)
954                                 return false;
955                         break;
956
957                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
958                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
959                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
960                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
961                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
962                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
963                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
964                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
965                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
966                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
967                         if (!features.textureCompressionETC2)
968                                 return false;
969                         break;
970
971                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
972                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
973                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
974                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
975                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
976                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
977                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
978                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
979                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
980                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
981                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
982                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
983                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
984                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
985                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
986                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
987                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
988                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
989                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
990                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
991                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
992                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
993                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
994                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
995                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
996                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
997                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
998                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
999                         if (!features.textureCompressionASTC_LDR)
1000                                 return false;
1001                         break;
1002
1003                 default:
1004                         break;
1005         }
1006
1007         const VkFormatProperties        formatProperties        = getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
1008         const VkFormatFeatureFlags      formatFeatures          = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
1009                                                                                                                                                                                          : formatProperties.optimalTilingFeatures);
1010
1011         if (!isUsageMatchesFeatures(info.usage, formatFeatures))
1012                 return false;
1013
1014         VkImageFormatProperties         imageFormatProperties;
1015         const VkResult                          result                          = vki.getPhysicalDeviceImageFormatProperties(
1016                                                                                                                 physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1017
1018         if (result == VK_SUCCESS)
1019         {
1020                 if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1021                         return false;
1022                 if (info.mipLevels > imageFormatProperties.maxMipLevels)
1023                         return false;
1024                 if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1025                         return false;
1026         }
1027
1028         return result == VK_SUCCESS;
1029 }
1030
1031 VkExtent3D makeExtentForImage (const VkImageType imageType)
1032 {
1033         VkExtent3D extent = { 64u, 64u, 4u };
1034
1035         if (imageType == VK_IMAGE_TYPE_1D)
1036                 extent.height = extent.depth = 1u;
1037         else if (imageType == VK_IMAGE_TYPE_2D)
1038                 extent.depth = 1u;
1039
1040         return extent;
1041 }
1042
1043 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
1044 {
1045         DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1046
1047         // D/S formats are laid out next to each other in the enum
1048         const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
1049
1050         return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
1051 }
1052
1053 std::string getImageInfoString (const VkImageCreateInfo& imageInfo)
1054 {
1055         std::ostringstream str;
1056
1057         switch (imageInfo.imageType)
1058         {
1059                 case VK_IMAGE_TYPE_1D:                  str << "1D "; break;
1060                 case VK_IMAGE_TYPE_2D:                  str << "2D "; break;
1061                 case VK_IMAGE_TYPE_3D:                  str << "3D "; break;
1062                 default:                                                break;
1063         }
1064
1065         switch (imageInfo.tiling)
1066         {
1067                 case VK_IMAGE_TILING_OPTIMAL:   str << "(optimal) "; break;
1068                 case VK_IMAGE_TILING_LINEAR:    str << "(linear) "; break;
1069                 default:                                                break;
1070         }
1071
1072         str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
1073         str << imageInfo.format << " ";
1074         str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
1075         str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
1076         str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";
1077
1078         return str.str();
1079 }
1080
1081 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params)
1082 {
1083         const VkFormat                          formats[]               =
1084         {
1085                 VK_FORMAT_R4G4_UNORM_PACK8,
1086                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1087                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1088                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1089                 VK_FORMAT_B5G6R5_UNORM_PACK16,
1090                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1091                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1092                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1093                 VK_FORMAT_R8_UNORM,
1094                 VK_FORMAT_R8_SNORM,
1095                 VK_FORMAT_R8_USCALED,
1096                 VK_FORMAT_R8_SSCALED,
1097                 VK_FORMAT_R8_UINT,
1098                 VK_FORMAT_R8_SINT,
1099                 VK_FORMAT_R8_SRGB,
1100                 VK_FORMAT_R8G8_UNORM,
1101                 VK_FORMAT_R8G8_SNORM,
1102                 VK_FORMAT_R8G8_USCALED,
1103                 VK_FORMAT_R8G8_SSCALED,
1104                 VK_FORMAT_R8G8_UINT,
1105                 VK_FORMAT_R8G8_SINT,
1106                 VK_FORMAT_R8G8_SRGB,
1107                 VK_FORMAT_R8G8B8_UNORM,
1108                 VK_FORMAT_R8G8B8_SNORM,
1109                 VK_FORMAT_R8G8B8_USCALED,
1110                 VK_FORMAT_R8G8B8_SSCALED,
1111                 VK_FORMAT_R8G8B8_UINT,
1112                 VK_FORMAT_R8G8B8_SINT,
1113                 VK_FORMAT_R8G8B8_SRGB,
1114                 VK_FORMAT_B8G8R8_UNORM,
1115                 VK_FORMAT_B8G8R8_SNORM,
1116                 VK_FORMAT_B8G8R8_USCALED,
1117                 VK_FORMAT_B8G8R8_SSCALED,
1118                 VK_FORMAT_B8G8R8_UINT,
1119                 VK_FORMAT_B8G8R8_SINT,
1120                 VK_FORMAT_B8G8R8_SRGB,
1121                 VK_FORMAT_R8G8B8A8_UNORM,
1122                 VK_FORMAT_R8G8B8A8_SNORM,
1123                 VK_FORMAT_R8G8B8A8_USCALED,
1124                 VK_FORMAT_R8G8B8A8_SSCALED,
1125                 VK_FORMAT_R8G8B8A8_UINT,
1126                 VK_FORMAT_R8G8B8A8_SINT,
1127                 VK_FORMAT_R8G8B8A8_SRGB,
1128                 VK_FORMAT_B8G8R8A8_UNORM,
1129                 VK_FORMAT_B8G8R8A8_SNORM,
1130                 VK_FORMAT_B8G8R8A8_USCALED,
1131                 VK_FORMAT_B8G8R8A8_SSCALED,
1132                 VK_FORMAT_B8G8R8A8_UINT,
1133                 VK_FORMAT_B8G8R8A8_SINT,
1134                 VK_FORMAT_B8G8R8A8_SRGB,
1135                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1136                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1137                 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1138                 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1139                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1140                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1141                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1142                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1143                 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1144                 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1145                 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1146                 VK_FORMAT_A2R10G10B10_UINT_PACK32,
1147                 VK_FORMAT_A2R10G10B10_SINT_PACK32,
1148                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1149                 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1150                 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1151                 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1152                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1153                 VK_FORMAT_A2B10G10R10_SINT_PACK32,
1154                 VK_FORMAT_R16_UNORM,
1155                 VK_FORMAT_R16_SNORM,
1156                 VK_FORMAT_R16_USCALED,
1157                 VK_FORMAT_R16_SSCALED,
1158                 VK_FORMAT_R16_UINT,
1159                 VK_FORMAT_R16_SINT,
1160                 VK_FORMAT_R16_SFLOAT,
1161                 VK_FORMAT_R16G16_UNORM,
1162                 VK_FORMAT_R16G16_SNORM,
1163                 VK_FORMAT_R16G16_USCALED,
1164                 VK_FORMAT_R16G16_SSCALED,
1165                 VK_FORMAT_R16G16_UINT,
1166                 VK_FORMAT_R16G16_SINT,
1167                 VK_FORMAT_R16G16_SFLOAT,
1168                 VK_FORMAT_R16G16B16_UNORM,
1169                 VK_FORMAT_R16G16B16_SNORM,
1170                 VK_FORMAT_R16G16B16_USCALED,
1171                 VK_FORMAT_R16G16B16_SSCALED,
1172                 VK_FORMAT_R16G16B16_UINT,
1173                 VK_FORMAT_R16G16B16_SINT,
1174                 VK_FORMAT_R16G16B16_SFLOAT,
1175                 VK_FORMAT_R16G16B16A16_UNORM,
1176                 VK_FORMAT_R16G16B16A16_SNORM,
1177                 VK_FORMAT_R16G16B16A16_USCALED,
1178                 VK_FORMAT_R16G16B16A16_SSCALED,
1179                 VK_FORMAT_R16G16B16A16_UINT,
1180                 VK_FORMAT_R16G16B16A16_SINT,
1181                 VK_FORMAT_R16G16B16A16_SFLOAT,
1182                 VK_FORMAT_R32_UINT,
1183                 VK_FORMAT_R32_SINT,
1184                 VK_FORMAT_R32_SFLOAT,
1185                 VK_FORMAT_R32G32_UINT,
1186                 VK_FORMAT_R32G32_SINT,
1187                 VK_FORMAT_R32G32_SFLOAT,
1188                 VK_FORMAT_R32G32B32_UINT,
1189                 VK_FORMAT_R32G32B32_SINT,
1190                 VK_FORMAT_R32G32B32_SFLOAT,
1191                 VK_FORMAT_R32G32B32A32_UINT,
1192                 VK_FORMAT_R32G32B32A32_SINT,
1193                 VK_FORMAT_R32G32B32A32_SFLOAT,
1194                 VK_FORMAT_R64_UINT,
1195                 VK_FORMAT_R64_SINT,
1196                 VK_FORMAT_R64_SFLOAT,
1197                 VK_FORMAT_R64G64_UINT,
1198                 VK_FORMAT_R64G64_SINT,
1199                 VK_FORMAT_R64G64_SFLOAT,
1200                 VK_FORMAT_R64G64B64_UINT,
1201                 VK_FORMAT_R64G64B64_SINT,
1202                 VK_FORMAT_R64G64B64_SFLOAT,
1203                 VK_FORMAT_R64G64B64A64_UINT,
1204                 VK_FORMAT_R64G64B64A64_SINT,
1205                 VK_FORMAT_R64G64B64A64_SFLOAT,
1206                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1207                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1208                 VK_FORMAT_D16_UNORM,
1209                 VK_FORMAT_X8_D24_UNORM_PACK32,
1210                 VK_FORMAT_D32_SFLOAT,
1211                 VK_FORMAT_S8_UINT,
1212                 VK_FORMAT_D16_UNORM_S8_UINT,
1213                 VK_FORMAT_D24_UNORM_S8_UINT,
1214                 VK_FORMAT_D32_SFLOAT_S8_UINT,
1215                 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
1216                 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
1217                 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
1218                 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1219                 VK_FORMAT_BC2_UNORM_BLOCK,
1220                 VK_FORMAT_BC2_SRGB_BLOCK,
1221                 VK_FORMAT_BC3_UNORM_BLOCK,
1222                 VK_FORMAT_BC3_SRGB_BLOCK,
1223                 VK_FORMAT_BC4_UNORM_BLOCK,
1224                 VK_FORMAT_BC4_SNORM_BLOCK,
1225                 VK_FORMAT_BC5_UNORM_BLOCK,
1226                 VK_FORMAT_BC5_SNORM_BLOCK,
1227                 VK_FORMAT_BC6H_UFLOAT_BLOCK,
1228                 VK_FORMAT_BC6H_SFLOAT_BLOCK,
1229                 VK_FORMAT_BC7_UNORM_BLOCK,
1230                 VK_FORMAT_BC7_SRGB_BLOCK,
1231                 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1232                 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1233                 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1234                 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1235                 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1236                 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1237                 VK_FORMAT_EAC_R11_UNORM_BLOCK,
1238                 VK_FORMAT_EAC_R11_SNORM_BLOCK,
1239                 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1240                 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1241                 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1242                 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
1243                 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
1244                 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1245                 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
1246                 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
1247                 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1248                 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
1249                 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
1250                 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1251                 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
1252                 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
1253                 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1254                 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
1255                 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
1256                 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1257                 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
1258                 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
1259                 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1260                 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
1261                 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
1262                 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1263                 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
1264                 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
1265                 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1266                 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
1267                 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
1268                 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1269                 VK_FORMAT_G8B8G8R8_422_UNORM_KHR,
1270                 VK_FORMAT_B8G8R8G8_422_UNORM_KHR,
1271                 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR,
1272                 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
1273                 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR,
1274                 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR,
1275                 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR,
1276                 VK_FORMAT_R10X6_UNORM_PACK16_KHR,
1277                 VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR,
1278                 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR,
1279                 VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR,
1280                 VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR,
1281                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR,
1282                 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR,
1283                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR,
1284                 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR,
1285                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR,
1286                 VK_FORMAT_R12X4_UNORM_PACK16_KHR,
1287                 VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR,
1288                 VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR,
1289                 VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR,
1290                 VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR,
1291                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR,
1292                 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR,
1293                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR,
1294                 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR,
1295                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR,
1296                 VK_FORMAT_G16B16G16R16_422_UNORM_KHR,
1297                 VK_FORMAT_B16G16R16G16_422_UNORM_KHR,
1298                 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR,
1299                 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR,
1300                 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR,
1301                 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR,
1302                 VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR
1303         };
1304         const DeviceInterface&          vk                              = context.getDeviceInterface();
1305         const InstanceInterface&        vki                             = context.getInstanceInterface();
1306         const VkDevice                          device                  = context.getDevice();
1307         const VkPhysicalDevice          physDevice              = context.getPhysicalDevice();
1308         const VkImageCreateFlags        sparseFlags             = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1309         const VkImageUsageFlags         transientFlags  = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1310
1311         preTestChecks(context, vki, physDevice, params.flags);
1312
1313         const VkPhysicalDeviceMemoryProperties  memoryProperties                = getPhysicalDeviceMemoryProperties(vki, physDevice);
1314         const deUint32                                                  notInitializedBits              = ~0u;
1315         const VkImageAspectFlags                                colorAspect                             = VK_IMAGE_ASPECT_COLOR_BIT;
1316         const VkImageAspectFlags                                depthStencilAspect              = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1317         const VkImageAspectFlags                                allAspects[2]                   = { colorAspect, depthStencilAspect };
1318         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
1319         bool                                                                    allPass                                 = true;
1320         deUint32                                                                numCheckedImages                = 0u;
1321
1322         log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
1323
1324         for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
1325         {
1326                 const VkImageAspectFlags        aspect                                  = allAspects[loopAspectNdx];
1327                 deUint32                                        previousMemoryTypeBits  = notInitializedBits;
1328
1329                 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1330                 {
1331                         const VkFormat format = formats[formatNdx];
1332
1333                         if  (isFormatMatchingAspect(format, aspect))
1334                         {
1335                                 // memoryTypeBits may differ between depth/stencil formats
1336                                 if (aspect == depthStencilAspect)
1337                                         previousMemoryTypeBits = notInitializedBits;
1338
1339                                 for (VkImageType                        loopImageType   = VK_IMAGE_TYPE_1D;                                     loopImageType   != VK_IMAGE_TYPE_LAST;                                  loopImageType   = nextEnum(loopImageType))
1340                                 for (VkImageCreateFlags         loopCreateFlags = (VkImageCreateFlags)0;                        loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags))
1341                                 for (VkImageUsageFlags          loopUsageFlags  = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;      loopUsageFlags  <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags  = nextFlagExcluding(loopUsageFlags, transientFlags))
1342                                 for (VkSampleCountFlagBits      loopSampleCount = VK_SAMPLE_COUNT_1_BIT;                        loopSampleCount <= VK_SAMPLE_COUNT_16_BIT;                              loopSampleCount = nextFlag(loopSampleCount))
1343                                 {
1344                                         const VkImageCreateFlags        actualCreateFlags       = loopCreateFlags | params.flags;
1345                                         const VkImageUsageFlags         actualUsageFlags        = loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1346                                         const bool                                      isCube                          = (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
1347                                         const VkImageCreateInfo         imageInfo                       =
1348                                         {
1349                                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
1350                                                 DE_NULL,                                                                        // const void*              pNext;
1351                                                 actualCreateFlags,                                                      // VkImageCreateFlags       flags;
1352                                                 loopImageType,                                                          // VkImageType              imageType;
1353                                                 format,                                                                 // VkFormat                 format;
1354                                                 makeExtentForImage(loopImageType),                      // VkExtent3D               extent;
1355                                                 1u,                                                                                     // uint32_t                 mipLevels;
1356                                                 (isCube ? 6u : 1u),                                                     // uint32_t                 arrayLayers;
1357                                                 loopSampleCount,                                                        // VkSampleCountFlagBits    samples;
1358                                                 params.tiling,                                                          // VkImageTiling            tiling;
1359                                                 actualUsageFlags,                                                       // VkImageUsageFlags        usage;
1360                                                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
1361                                                 0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
1362                                                 DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
1363                                                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
1364                                         };
1365
1366                                         m_currentTestImageInfo = imageInfo;
1367
1368                                         if (!isImageSupported(vki, physDevice, context.getDeviceExtensions(), m_currentTestImageInfo))
1369                                                 continue;
1370
1371                                         log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage;
1372                                         ++numCheckedImages;
1373
1374                                         tcu::ResultCollector result(log, "ERROR: ");
1375
1376                                         updateMemoryRequirements(vk, device);
1377
1378                                         verifyMemoryRequirements(result, memoryProperties);
1379
1380                                         // For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1381                                         result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1382                                                                         "memoryTypeBits differ from the ones in the previous image configuration");
1383
1384                                         if (result.getResult() != QP_TEST_RESULT_PASS)
1385                                                 allPass = false;
1386
1387                                         previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1388                                 }
1389                         }
1390                 }
1391         }
1392
1393         if (numCheckedImages == 0u)
1394                 log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;
1395
1396         return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1397 }
1398
1399
1400 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1401 {
1402 public:
1403         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
1404                                                                                          const ImageTestParams                                          params);
1405
1406 protected:
1407         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
1408                                                                                          const std::string&                                                     name,
1409                                                                                          const std::string&                                                     desc,
1410                                                                                          const ImageTestParams                                          arg0);
1411
1412         virtual void preTestChecks                              (Context&                                                                       context,
1413                                                                                          const InstanceInterface&                                       vki,
1414                                                                                          const VkPhysicalDevice                                         physDevice,
1415                                                                                          const VkImageCreateFlags                                       flags);
1416
1417         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
1418                                                                                          const VkDevice                                                         device);
1419 };
1420
1421
1422 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
1423 {
1424         ImageMemoryRequirementsExtended test;
1425
1426         return test.execTest(context, params);
1427 }
1428
1429 void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*          group,
1430                                                                                                                    const std::string&           name,
1431                                                                                                                    const std::string&           desc,
1432                                                                                                                    const ImageTestParams        arg0)
1433 {
1434         addFunctionCase(group, name, desc, testEntryPoint, arg0);
1435 }
1436
1437 void ImageMemoryRequirementsExtended::preTestChecks (Context&                                   context,
1438                                                                                                          const InstanceInterface&       vki,
1439                                                                                                          const VkPhysicalDevice         physDevice,
1440                                                                                                          const VkImageCreateFlags       createFlags)
1441 {
1442         const std::string extensionName("VK_KHR_get_memory_requirements2");
1443
1444         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1445                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1446
1447         ImageMemoryRequirementsOriginal::preTestChecks (context, vki, physDevice, createFlags);
1448 }
1449
1450 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&          vk,
1451                                                                                                                             const VkDevice                              device)
1452 {
1453         m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1454 }
1455
1456
1457 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
1458 {
1459 public:
1460         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
1461                                                                                          const ImageTestParams                                          params);
1462
1463 protected:
1464         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
1465                                                                                          const std::string&                                                     name,
1466                                                                                          const std::string&                                                     desc,
1467                                                                                          const ImageTestParams                                          arg0);
1468
1469         virtual void preTestChecks                              (Context&                                                                       context,
1470                                                                                          const InstanceInterface&                                       vki,
1471                                                                                          const VkPhysicalDevice                                         physDevice,
1472                                                                                          const VkImageCreateFlags                                       flags);
1473
1474         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
1475                                                                                          const VkDevice                                                         device);
1476
1477         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
1478                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties);
1479
1480 protected:
1481         VkBool32        m_currentTestPrefersDedicatedAllocation;
1482         VkBool32        m_currentTestRequiresDedicatedAllocation;
1483 };
1484
1485
1486 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params)
1487 {
1488         ImageMemoryRequirementsDedicatedAllocation test;
1489
1490         return test.execTest(context, params);
1491 }
1492
1493 void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*               group,
1494                                                                                                                                           const std::string&            name,
1495                                                                                                                                           const std::string&            desc,
1496                                                                                                                                           const ImageTestParams         arg0)
1497 {
1498         addFunctionCase(group, name, desc, testEntryPoint, arg0);
1499 }
1500
1501 void ImageMemoryRequirementsDedicatedAllocation::preTestChecks (Context&                                        context,
1502                                                                                                                                 const InstanceInterface&        vki,
1503                                                                                                                                 const VkPhysicalDevice          physDevice,
1504                                                                                                                                 const VkImageCreateFlags        createFlags)
1505 {
1506         const std::string extensionName("VK_KHR_dedicated_allocation");
1507
1508         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1509                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1510
1511         ImageMemoryRequirementsExtended::preTestChecks (context, vki, physDevice, createFlags);
1512 }
1513
1514
1515 void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&       vk,
1516                                                                                                                                                    const VkDevice                       device)
1517 {
1518         const deUint32                                          invalidVkBool32                 = static_cast<deUint32>(~0);
1519
1520         VkMemoryDedicatedRequirementsKHR        dedicatedRequirements   =
1521         {
1522                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,    // VkStructureType      sType
1523                 DE_NULL,                                                                                                // void*                        pNext
1524                 invalidVkBool32,                                                                                // VkBool32                     prefersDedicatedAllocation
1525                 invalidVkBool32                                                                                 // VkBool32                     requiresDedicatedAllocation
1526         };
1527
1528         m_currentTestRequirements                                       = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements);
1529         m_currentTestPrefersDedicatedAllocation         = dedicatedRequirements.prefersDedicatedAllocation;
1530         m_currentTestRequiresDedicatedAllocation        = dedicatedRequirements.requiresDedicatedAllocation;
1531 }
1532
1533 void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&                                                result,
1534                                                                                                                                                    const VkPhysicalDeviceMemoryProperties&      deviceMemoryProperties)
1535 {
1536         ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties);
1537
1538         result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
1539                 "Non-bool value in m_currentTestPrefersDedicatedAllocation");
1540
1541         result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
1542                 "Test design expects m_currentTestRequiresDedicatedAllocation to be false");
1543
1544         result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
1545                 "Preferred and required flags for dedicated memory cannot be set to true at the same time");
1546 }
1547
1548 void populateCoreTestGroup (tcu::TestCaseGroup* group)
1549 {
1550         BufferMemoryRequirementsOriginal        bufferTest;
1551         ImageMemoryRequirementsOriginal         imageTest;
1552
1553         bufferTest.populateTestGroup(group);
1554         imageTest.populateTestGroup(group);
1555 }
1556
1557 void populateExtendedTestGroup (tcu::TestCaseGroup* group)
1558 {
1559         BufferMemoryRequirementsExtended        bufferTest;
1560         ImageMemoryRequirementsExtended         imageTest;
1561
1562         bufferTest.populateTestGroup(group);
1563         imageTest.populateTestGroup(group);
1564 }
1565
1566 void populateDedicatedAllocationTestGroup (tcu::TestCaseGroup* group)
1567 {
1568         BufferMemoryRequirementsDedicatedAllocation     bufferTest;
1569         ImageMemoryRequirementsDedicatedAllocation      imageTest;
1570
1571         bufferTest.populateTestGroup(group);
1572         imageTest.populateTestGroup(group);
1573 }
1574
1575 bool isMultiplaneImageSupported (const InstanceInterface&       vki,
1576                                                                  const VkPhysicalDevice         physicalDevice,
1577                                                                  const VkImageCreateInfo&       info)
1578 {
1579         if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
1580                 return false;
1581
1582         if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
1583                 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
1584                 return false;
1585
1586         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physicalDevice);
1587
1588         if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
1589         {
1590                 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
1591
1592                 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
1593                         return false;
1594         }
1595
1596         const VkFormatProperties        formatProperties        = getPhysicalDeviceFormatProperties(vki, physicalDevice, info.format);
1597         const VkFormatFeatureFlags      formatFeatures          = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
1598                                                                                                                                                                                          : formatProperties.optimalTilingFeatures);
1599
1600         if (!isUsageMatchesFeatures(info.usage, formatFeatures))
1601                 return false;
1602
1603         VkImageFormatProperties         imageFormatProperties;
1604         const VkResult                          result                          = vki.getPhysicalDeviceImageFormatProperties(
1605                                                                                                                 physicalDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1606
1607         if (result == VK_SUCCESS)
1608         {
1609                 if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1610                         return false;
1611                 if (info.mipLevels > imageFormatProperties.maxMipLevels)
1612                         return false;
1613                 if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1614                         return false;
1615         }
1616
1617         return result == VK_SUCCESS;
1618 }
1619
1620 tcu::TestStatus testMultiplaneImages (Context& context, ImageTestParams params)
1621 {
1622         const VkFormat multiplaneFormats[] =
1623         {
1624                 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR,
1625                 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
1626                 VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR,
1627                 VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR,
1628                 VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR,
1629                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR,
1630                 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR,
1631                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR,
1632                 VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR,
1633                 VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR,
1634                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR,
1635                 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR,
1636                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR,
1637                 VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR,
1638                 VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR,
1639                 VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR,
1640                 VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR,
1641                 VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR,
1642                 VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR
1643         };
1644         {
1645                 const std::string extensionName("VK_KHR_get_memory_requirements2");
1646
1647                 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1648                         TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1649         }
1650         {
1651                 const std::string extensionName("VK_KHR_sampler_ycbcr_conversion");
1652
1653                 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1654                         TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1655         }
1656
1657         const DeviceInterface&                                  vk                                      = context.getDeviceInterface();
1658         const InstanceInterface&                                vki                                     = context.getInstanceInterface();
1659         const VkDevice                                                  device                          = context.getDevice();
1660         const VkPhysicalDevice                                  physicalDevice          = context.getPhysicalDevice();
1661         const VkImageCreateFlags                                sparseFlags                     = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1662         const VkImageUsageFlags                                 transientFlags          = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1663         const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vki, physicalDevice);
1664         tcu::TestLog&                                                   log                                     = context.getTestContext().getLog();
1665         tcu::ResultCollector                                    result                          (log, "ERROR: ");
1666         deUint32                                                                errorCount                      = 0;
1667
1668         log << TestLog::Message << "Memory properties: " << memoryProperties << TestLog::EndMessage;
1669
1670         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(multiplaneFormats); formatNdx++)
1671         {
1672                 for (VkImageCreateFlags         loopCreateFlags = (VkImageCreateFlags)0;                        loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags))
1673                 for (VkImageUsageFlags          loopUsageFlags  = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;      loopUsageFlags  <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags  = nextFlagExcluding(loopUsageFlags, transientFlags))
1674                 {
1675                         const VkFormat                          format                          = multiplaneFormats[formatNdx];
1676                         const VkImageCreateFlags        actualCreateFlags       = loopCreateFlags | params.flags;
1677                         const VkImageUsageFlags         actualUsageFlags        = loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1678                         const VkImageCreateInfo         imageInfo                       =
1679                         {
1680                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType          sType;
1681                                 DE_NULL,                                                                // const void*              pNext;
1682                                 actualCreateFlags,                                              // VkImageCreateFlags       flags;
1683                                 VK_IMAGE_TYPE_2D,                                               // VkImageType              imageType;
1684                                 format,                                                                 // VkFormat                 format;
1685                                 { 64u, 64u, 1u, },                                              // VkExtent3D               extent;
1686                                 1u,                                                                             // uint32_t                 mipLevels;
1687                                 1u,                                                                             // uint32_t                 arrayLayers;
1688                                 VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples;
1689                                 params.tiling,                                                  // VkImageTiling            tiling;
1690                                 actualUsageFlags,                                               // VkImageUsageFlags        usage;
1691                                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode;
1692                                 0u,                                                                             // uint32_t                 queueFamilyIndexCount;
1693                                 DE_NULL,                                                                // const uint32_t*          pQueueFamilyIndices;
1694                                 VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout            initialLayout;
1695                         };
1696
1697                         if (isMultiplaneImageSupported(vki, physicalDevice, imageInfo))
1698                         {
1699                                 const Unique<VkImage>                   image                   (createImage(vk, device, &imageInfo));
1700
1701                                 log << tcu::TestLog::Message << "- " << getImageInfoString(imageInfo) << tcu::TestLog::EndMessage;
1702
1703                                 for (deUint32 planeNdx = 0; planeNdx < (deUint32)getPlaneCount(format); planeNdx++)
1704                                 {
1705                                         const VkImageAspectFlagBits                                     aspect          = getPlaneAspect(planeNdx);
1706                                         const VkImagePlaneMemoryRequirementsInfoKHR     aspectInfo      =
1707                                         {
1708                                                 VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR,
1709                                                 DE_NULL,
1710                                                 aspect
1711                                         };
1712                                         const VkImageMemoryRequirementsInfo2KHR         info            =
1713                                         {
1714                                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,
1715                                                 (actualCreateFlags & VK_IMAGE_CREATE_DISJOINT_BIT_KHR) == 0 ? DE_NULL : &aspectInfo,
1716                                                 *image
1717                                         };
1718                                         VkMemoryRequirements2KHR                                        requirements    =
1719                                         {
1720                                                 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
1721                                                 DE_NULL,
1722                                                 { 0u, 0u, 0u }
1723                                         };
1724
1725                                         vk.getImageMemoryRequirements2KHR(device, &info, &requirements);
1726
1727                                         log << TestLog::Message << "Aspect: " << getImageAspectFlagsStr(aspect) << ", Requirements: " << requirements << TestLog::EndMessage;
1728
1729                                         result.check(deIsPowerOfTwo64(static_cast<deUint64>(requirements.memoryRequirements.alignment)), "VkMemoryRequirements alignment isn't power of two");
1730
1731                                         if (result.check(requirements.memoryRequirements.memoryTypeBits != 0, "No supported memory types"))
1732                                         {
1733                                                 bool    hasHostVisibleType      = false;
1734
1735                                                 for (deUint32 memoryTypeIndex = 0; (0x1u << memoryTypeIndex) <= requirements.memoryRequirements.memoryTypeBits; memoryTypeIndex++)
1736                                                 {
1737                                                         if (result.check(memoryTypeIndex < memoryProperties.memoryTypeCount, "Unknown memory type bits set in memory requirements"))
1738                                                         {
1739                                                                 const VkMemoryPropertyFlags     propertyFlags   (memoryProperties.memoryTypes[memoryTypeIndex].propertyFlags);
1740
1741                                                                 if (propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
1742                                                                         hasHostVisibleType = true;
1743
1744                                                                 if (propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
1745                                                                 {
1746                                                                         result.check((imageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
1747                                                                                 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
1748                                                                 }
1749                                                         }
1750                                                         else
1751                                                                 break;
1752                                                 }
1753
1754                                                 result.check(params.tiling != VK_IMAGE_TILING_LINEAR || hasHostVisibleType, "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
1755                                         }
1756                                 }
1757                         }
1758                 }
1759         }
1760
1761         if (errorCount > 1)
1762                 return tcu::TestStatus(result.getResult(), "Failed " + de::toString(errorCount) + " cases.");
1763         else
1764                 return tcu::TestStatus(result.getResult(), result.getMessage());
1765 }
1766
1767 void populateMultiplaneTestGroup (tcu::TestCaseGroup* group)
1768 {
1769         const struct
1770         {
1771                 VkImageCreateFlags              flags;
1772                 bool                                    transient;
1773                 const char* const               name;
1774         } imageFlagsCases[] =
1775         {
1776                 { (VkImageCreateFlags)0,                                                                                                                                                                                                false,  "regular"                                       },
1777                 { (VkImageCreateFlags)0,                                                                                                                                                                                                true,   "transient"                                     },
1778                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                   false,  "sparse"                                        },
1779                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,                                                                                    false,  "sparse_residency"                      },
1780                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT                                                                                    | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_aliased"                        },
1781                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT             | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_residency_aliased"      },
1782         };
1783         const struct
1784         {
1785                 VkImageTiling   value;
1786                 const char*             name;
1787         } tilings[] =
1788         {
1789                 { VK_IMAGE_TILING_OPTIMAL,      "optimal"       },
1790                 { VK_IMAGE_TILING_LINEAR,       "linear"        }
1791         };
1792
1793         for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
1794         for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); ++tilingNdx)
1795         {
1796                 const VkImageCreateFlags        flags           = imageFlagsCases[flagsNdx].flags;
1797                 const bool                                      transient       = imageFlagsCases[flagsNdx].transient;
1798                 const VkImageTiling                     tiling          = tilings[tilingNdx].value;
1799                 const ImageTestParams           params          (flags, tiling, transient);
1800                 const std::string                       name            = std::string(imageFlagsCases[flagsNdx].name) + "_" + tilings[tilingNdx].name;
1801
1802                 if (tiling == VK_IMAGE_TILING_LINEAR && (flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0)
1803                         continue;
1804
1805                 addFunctionCase(group, name, name, testMultiplaneImages, params);
1806         }
1807 }
1808
1809 } // anonymous
1810
1811
1812 tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
1813 {
1814         de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements", "Buffer and image memory requirements"));
1815
1816         requirementsGroup->addChild(createTestGroup(testCtx, "core",                                    "Memory requirements tests with core functionality",                                            populateCoreTestGroup));
1817         requirementsGroup->addChild(createTestGroup(testCtx, "extended",                                "Memory requirements tests with extension VK_KHR_get_memory_requirements2",     populateExtendedTestGroup));
1818         requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation",    "Memory requirements tests with extension VK_KHR_dedicated_allocation",         populateDedicatedAllocationTestGroup));
1819         requirementsGroup->addChild(createTestGroup(testCtx, "multiplane_image",                "Memory requirements tests with vkGetImagePlaneMemoryRequirements",                     populateMultiplaneTestGroup));
1820
1821         return requirementsGroup.release();
1822 }
1823
1824 } // memory
1825 } // vkt