Test VK_KHR_dedicated_allocation mem requirement queries
[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
36 #include "deUniquePtr.hpp"
37 #include "deStringUtil.hpp"
38 #include "deSTLUtil.hpp"
39
40 #include "tcuResultCollector.hpp"
41 #include "tcuTestLog.hpp"
42
43 namespace vkt
44 {
45 namespace memory
46 {
47 namespace
48 {
49 using namespace vk;
50 using de::MovePtr;
51
52 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
53 {
54         const VkBufferCreateInfo createInfo =
55         {
56                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType        sType;
57                 DE_NULL,                                                                        // const void*            pNext;
58                 flags,                                                                          // VkBufferCreateFlags    flags;
59                 size,                                                                           // VkDeviceSize           size;
60                 usage,                                                                          // VkBufferUsageFlags     usage;
61                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode          sharingMode;
62                 0u,                                                                                     // uint32_t               queueFamilyIndexCount;
63                 DE_NULL,                                                                        // const uint32_t*        pQueueFamilyIndices;
64         };
65         return createBuffer(vk, device, &createInfo);
66 }
67
68 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
69 {
70         const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
71         return getBufferMemoryRequirements(vk, device, *buffer);
72 }
73
74 VkMemoryRequirements getBufferMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL)
75 {
76         const Unique<VkBuffer>                          buffer          (makeBuffer(vk, device, size, flags, usage));
77         VkBufferMemoryRequirementsInfo2KHR      info    =
78         {
79                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,        // VkStructureType      sType
80                 DE_NULL,                                                                                                        // const void*          pNext
81                 *buffer                                                                                                         // VkBuffer                     buffer
82         };
83         VkMemoryRequirements2KHR                        req2    =
84         {
85                 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,                            // VkStructureType              sType
86                 next,                                                                                                           // void*                                pNext
87                 {0, 0, 0}                                                                                                       // VkMemoryRequirements memoryRequirements
88         };
89
90         vk.getBufferMemoryRequirements2KHR(device, &info, &req2);
91
92         return req2.memoryRequirements;
93 }
94
95 VkMemoryRequirements getImageMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL)
96 {
97         const Unique<VkImage> image(createImage(vk, device, &createInfo));
98
99         VkImageMemoryRequirementsInfo2KHR       info    =
100         {
101                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR,         // VkStructureType      sType
102                 DE_NULL,                                                                                                        // const void*          pNext
103                 *image                                                                                                          // VkImage                      image
104         };
105         VkMemoryRequirements2KHR                        req2    =
106         {
107                 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,                            // VkStructureType              sType
108                 next,                                                                                                           // void*                                pNext
109                 {0, 0, 0}                                                                                                       // VkMemoryRequirements memoryRequirements
110         };
111
112         vk.getImageMemoryRequirements2KHR(device, &info, &req2);
113
114         return req2.memoryRequirements;
115 }
116
117 //! Get an index of each set bit, starting from the least significant bit.
118 std::vector<deUint32> bitsToIndices (deUint32 bits)
119 {
120         std::vector<deUint32> indices;
121         for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1)
122         {
123                 if (bits & 1u)
124                         indices.push_back(i);
125         }
126         return indices;
127 }
128
129 template<typename T>
130 T nextEnum (T value)
131 {
132         return static_cast<T>(static_cast<deUint32>(value) + 1);
133 }
134
135 template<typename T>
136 T nextFlag (T value)
137 {
138         if (value)
139                 return static_cast<T>(static_cast<deUint32>(value) << 1);
140         else
141                 return static_cast<T>(1);
142 }
143
144 template<typename T>
145 T nextFlagExcluding (T value, T excludedFlags)
146 {
147         deUint32 tmp = static_cast<deUint32>(value);
148         while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags));
149         return static_cast<T>(tmp);
150 }
151
152 bool validValueVkBool32 (const VkBool32 value)
153 {
154         return (value == VK_FALSE || value == VK_TRUE);
155 }
156
157 class IBufferMemoryRequirements
158 {
159 public:
160         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group) = 0;
161
162 protected:
163         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
164                                                                                          const std::string&                                                     name,
165                                                                                          const std::string&                                                     desc,
166                                                                                          VkBufferCreateFlags                                            arg0) = 0;
167
168         virtual tcu::TestStatus execTest                (Context&                                                                       context,
169                                                                                          const VkBufferCreateFlags                                      bufferFlags) = 0;
170
171         virtual void preTestChecks                              (Context&                                                                       context,
172                                                                                          const InstanceInterface&                                       vki,
173                                                                                          const VkPhysicalDevice                                         physDevice,
174                                                                                          const VkBufferCreateFlags                                      flags) = 0;
175
176         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
177                                                                                          const VkDevice                                                         device,
178                                                                                          const VkDeviceSize                                                     size,
179                                                                                          const VkBufferCreateFlags                                      flags,
180                                                                                          const VkBufferUsageFlags                                       usage,
181                                                                                          const bool                                                                     all) = 0;
182
183         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
184                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
185                                                                                          const VkPhysicalDeviceLimits&                          limits,
186                                                                                          const VkBufferCreateFlags                                      bufferFlags,
187                                                                                          const VkBufferUsageFlags                                       usage) = 0;
188 };
189
190 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
191 {
192         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
193                                                                                          const VkBufferCreateFlags                                      bufferFlags);
194
195 public:
196         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group);
197
198 protected:
199         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
200                                                                                          const std::string&                                                     name,
201                                                                                          const std::string&                                                     desc,
202                                                                                          VkBufferCreateFlags                                            arg0);
203
204         virtual tcu::TestStatus execTest                (Context&                                                                       context,
205                                                                                          const VkBufferCreateFlags                                      bufferFlags);
206
207         virtual void preTestChecks                              (Context&                                                                       context,
208                                                                                          const InstanceInterface&                                       vki,
209                                                                                          const VkPhysicalDevice                                         physDevice,
210                                                                                          const VkBufferCreateFlags                                      flags);
211
212         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
213                                                                                          const VkDevice                                                         device,
214                                                                                          const VkDeviceSize                                                     size,
215                                                                                          const VkBufferCreateFlags                                      flags,
216                                                                                          const VkBufferUsageFlags                                       usage,
217                                                                                          const bool                                                                     all);
218
219         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
220                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
221                                                                                          const VkPhysicalDeviceLimits&                          limits,
222                                                                                          const VkBufferCreateFlags                                      bufferFlags,
223                                                                                          const VkBufferUsageFlags                                       usage);
224
225 protected:
226         VkMemoryRequirements    m_allUsageFlagsRequirements;
227         VkMemoryRequirements    m_currentTestRequirements;
228 };
229
230
231 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
232 {
233         BufferMemoryRequirementsOriginal test;
234
235         return test.execTest(context, bufferFlags);
236 }
237
238 void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
239 {
240         const struct
241         {
242                 VkBufferCreateFlags             flags;
243                 const char* const               name;
244         } bufferCases[] =
245         {
246                 { (VkBufferCreateFlags)0,                                                                                                                                                                                               "regular"                                       },
247                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                  "sparse"                                        },
248                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,                                                                                  "sparse_residency"                      },
249                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT                                                                                   | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,  "sparse_aliased"                        },
250                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT   | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,  "sparse_residency_aliased"      },
251         };
252
253         de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", ""));
254
255         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
256                 addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, "", bufferCases[ndx].flags);
257
258         group->addChild(bufferGroup.release());
259 }
260
261 void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group,
262                                                                                                                         const std::string&      name,
263                                                                                                                         const std::string&      desc,
264                                                                                                                         VkBufferCreateFlags     arg0)
265 {
266         addFunctionCase(group, name, desc, testEntryPoint, arg0);
267 }
268
269 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags)
270 {
271         const DeviceInterface&                                  vk                      = context.getDeviceInterface();
272         const InstanceInterface&                                vki                     = context.getInstanceInterface();
273         const VkDevice                                                  device          = context.getDevice();
274         const VkPhysicalDevice                                  physDevice      = context.getPhysicalDevice();
275
276         preTestChecks(context, vki, physDevice, bufferFlags);
277
278         const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vki, physDevice);
279         const VkPhysicalDeviceLimits                    limits                          = getPhysicalDeviceProperties(vki, physDevice).limits;
280         const VkBufferUsageFlags                                allUsageFlags           = static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
281         tcu::TestLog&                                                   log                                     = context.getTestContext().getLog();
282         bool                                                                    allPass                         = true;
283
284         const VkDeviceSize sizeCases[] =
285         {
286                 1    * 1024,
287                 8    * 1024,
288                 64   * 1024,
289                 1024 * 1024,
290         };
291
292         // Updates m_allUsageFlags* fields
293         updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
294
295         for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
296         {
297                 deUint32                previousMemoryTypeBits  = 0u;
298                 VkDeviceSize    previousAlignment               = 0u;
299
300                 log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;
301
302                 for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
303                 {
304                         log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
305
306                         tcu::ResultCollector result(log, "ERROR: ");
307
308                         // Updates m_allUsageFlags* fields
309                         updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
310
311                         // Check:
312                         // - requirements for a particular buffer usage
313                         // - memoryTypeBits are a subset of bits for requirements with all usage flags combined
314                         verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
315
316                         // Check that for the same usage and create flags:
317                         // - memoryTypeBits are the same
318                         // - alignment is the same
319                         if (pSize > sizeCases)
320                         {
321                                 result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
322                                         "memoryTypeBits differ from the ones in the previous buffer size");
323
324                                 result.check(m_currentTestRequirements.alignment == previousAlignment,
325                                         "alignment differs from the one in the previous buffer size");
326                         }
327
328                         if (result.getResult() != QP_TEST_RESULT_PASS)
329                                 allPass = false;
330
331                         previousMemoryTypeBits  = m_currentTestRequirements.memoryTypeBits;
332                         previousAlignment               = m_currentTestRequirements.alignment;
333                 }
334
335                 if (!allPass)
336                         break;
337         }
338
339         return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
340 }
341
342 void BufferMemoryRequirementsOriginal::preTestChecks (Context&                                                          ,
343                                                                                                           const InstanceInterface&                              vki,
344                                                                                                           const VkPhysicalDevice                                physDevice,
345                                                                                                           const VkBufferCreateFlags                             flags)
346 {
347         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
348
349         if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
350                 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
351
352         if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer)
353                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer");
354
355         if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
356                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
357 }
358
359 void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface&         vk,
360                                                                                                                                  const VkDevice                         device,
361                                                                                                                                  const VkDeviceSize                     size,
362                                                                                                                                  const VkBufferCreateFlags      flags,
363                                                                                                                                  const VkBufferUsageFlags       usage,
364                                                                                                                                  const bool                                     all)
365 {
366         if (all)
367         {
368                 m_allUsageFlagsRequirements     = getBufferMemoryRequirements(vk, device, size, flags, usage);
369         }
370         else
371         {
372                 m_currentTestRequirements       = getBufferMemoryRequirements(vk, device, size, flags, usage);
373         }
374 }
375
376 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&                                          result,
377                                                                                                                                  const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
378                                                                                                                                  const VkPhysicalDeviceLimits&                          limits,
379                                                                                                                                  const VkBufferCreateFlags                                      bufferFlags,
380                                                                                                                                  const VkBufferUsageFlags                                       usage)
381 {
382         if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
383         {
384                 typedef std::vector<deUint32>::const_iterator   IndexIterator;
385                 const std::vector<deUint32>                                             usedMemoryTypeIndices                   = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
386                 bool                                                                                    deviceLocalMemoryFound                  = false;
387                 bool                                                                                    hostVisibleCoherentMemoryFound  = false;
388
389                 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
390                 {
391                         if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
392                         {
393                                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
394                                 continue;
395                         }
396
397                         const VkMemoryPropertyFlags     memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
398
399                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
400                                 deviceLocalMemoryFound = true;
401
402                         if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
403                                 hostVisibleCoherentMemoryFound = true;
404
405                         result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
406                                 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
407                 }
408
409                 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
410                         "VkMemoryRequirements alignment isn't power of two");
411
412                 if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
413                 {
414                         result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
415                                 "VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
416                 }
417
418                 if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
419                 {
420                         result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
421                                 "VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
422                 }
423
424                 if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
425                 {
426                         result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
427                                 "VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
428                 }
429
430                 result.check(deviceLocalMemoryFound,
431                         "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
432
433                 result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
434                         "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
435
436                 result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits,
437                         "Memory type bits aren't a superset of memory type bits for all usage flags combined");
438         }
439 }
440
441 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
442 {
443         static tcu::TestStatus testEntryPoint   (Context&                                       context,
444                                                                                          const VkBufferCreateFlags      bufferFlags);
445
446 protected:
447         virtual void addFunctionTestCase                (tcu::TestCaseGroup*            group,
448                                                                                          const std::string&                     name,
449                                                                                          const std::string&                     desc,
450                                                                                          VkBufferCreateFlags            arg0);
451
452         virtual void preTestChecks                              (Context&                                       context,
453                                                                                          const InstanceInterface&       vki,
454                                                                                          const VkPhysicalDevice         physDevice,
455                                                                                          const VkBufferCreateFlags      flags);
456
457         virtual void updateMemoryRequirements   (const DeviceInterface&         vk,
458                                                                                          const VkDevice                         device,
459                                                                                          const VkDeviceSize                     size,
460                                                                                          const VkBufferCreateFlags      flags,
461                                                                                          const VkBufferUsageFlags       usage,
462                                                                                          const bool                                     all);
463 };
464
465 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
466 {
467         BufferMemoryRequirementsExtended test;
468
469         return test.execTest(context, bufferFlags);
470 }
471
472 void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group,
473                                                                                                                         const std::string&      name,
474                                                                                                                         const std::string&      desc,
475                                                                                                                         VkBufferCreateFlags     arg0)
476 {
477         addFunctionCase(group, name, desc, testEntryPoint, arg0);
478 }
479
480 void BufferMemoryRequirementsExtended::preTestChecks (Context&                                  context,
481                                                                                                           const InstanceInterface&      vki,
482                                                                                                           const VkPhysicalDevice        physDevice,
483                                                                                                           const VkBufferCreateFlags     flags)
484 {
485         const std::string extensionName("VK_KHR_get_memory_requirements2");
486
487         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
488                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
489
490         BufferMemoryRequirementsOriginal::preTestChecks(context, vki, physDevice, flags);
491 }
492
493 void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&         vk,
494                                                                                                                                  const VkDevice                         device,
495                                                                                                                                  const VkDeviceSize                     size,
496                                                                                                                                  const VkBufferCreateFlags      flags,
497                                                                                                                                  const VkBufferUsageFlags       usage,
498                                                                                                                                  const bool                                     all)
499 {
500         if (all)
501         {
502                 m_allUsageFlagsRequirements     = getBufferMemoryRequirements2(vk, device, size, flags, usage);
503         }
504         else
505         {
506                 m_currentTestRequirements       = getBufferMemoryRequirements2(vk, device, size, flags, usage);
507         }
508 }
509
510
511 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
512 {
513         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
514                                                                                          const VkBufferCreateFlags                                      bufferFlags);
515
516 protected:
517         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
518                                                                                          const std::string&                                                     name,
519                                                                                          const std::string&                                                     desc,
520                                                                                          VkBufferCreateFlags                                            arg0);
521
522         virtual void preTestChecks                              (Context&                                                                       context,
523                                                                                          const InstanceInterface&                                       vki,
524                                                                                          const VkPhysicalDevice                                         physDevice,
525                                                                                          const VkBufferCreateFlags                                      flags);
526
527         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
528                                                                                          const VkDevice                                                         device,
529                                                                                          const VkDeviceSize                                                     size,
530                                                                                          const VkBufferCreateFlags                                      flags,
531                                                                                          const VkBufferUsageFlags                                       usage,
532                                                                                          const bool                                                                     all);
533
534         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
535                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
536                                                                                          const VkPhysicalDeviceLimits&                          limits,
537                                                                                          const VkBufferCreateFlags                                      bufferFlags,
538                                                                                          const VkBufferUsageFlags                                       usage);
539
540 protected:
541         VkBool32        m_allUsageFlagsPrefersDedicatedAllocation;
542         VkBool32        m_allUsageFlagsRequiresDedicatedAllocation;
543
544         VkBool32        m_currentTestPrefersDedicatedAllocation;
545         VkBool32        m_currentTestRequiresDedicatedAllocation;
546 };
547
548
549 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
550 {
551         BufferMemoryRequirementsDedicatedAllocation test;
552
553         return test.execTest(context, bufferFlags);
554 }
555
556 void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*      group,
557                                                                                                                                            const std::string&   name,
558                                                                                                                                            const std::string&   desc,
559                                                                                                                                            VkBufferCreateFlags  arg0)
560 {
561         addFunctionCase(group, name, desc, testEntryPoint, arg0);
562 }
563
564 void BufferMemoryRequirementsDedicatedAllocation::preTestChecks (Context&                                       context,
565                                                                                                                                  const InstanceInterface&       vki,
566                                                                                                                                  const VkPhysicalDevice         physDevice,
567                                                                                                                                  const VkBufferCreateFlags      flags)
568 {
569         const std::string extensionName("VK_KHR_dedicated_allocation");
570
571         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
572                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
573
574         BufferMemoryRequirementsExtended::preTestChecks(context, vki, physDevice, flags);
575 }
576
577 void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&              vk,
578                                                                                                                                                         const VkDevice                          device,
579                                                                                                                                                         const VkDeviceSize                      size,
580                                                                                                                                                         const VkBufferCreateFlags       flags,
581                                                                                                                                                         const VkBufferUsageFlags        usage,
582                                                                                                                                                         const bool                                      all)
583 {
584         const deUint32                                          invalidVkBool32                 = static_cast<deUint32>(~0);
585
586         VkMemoryDedicatedRequirementsKHR        dedicatedRequirements   =
587         {
588                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,    // VkStructureType      sType
589                 DE_NULL,                                                                                                // void*                        pNext
590                 invalidVkBool32,                                                                                // VkBool32                     prefersDedicatedAllocation
591                 invalidVkBool32                                                                                 // VkBool32                     requiresDedicatedAllocation
592         };
593
594         if (all)
595         {
596                 m_allUsageFlagsRequirements                                     = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
597                 m_allUsageFlagsPrefersDedicatedAllocation       = dedicatedRequirements.prefersDedicatedAllocation;
598                 m_allUsageFlagsRequiresDedicatedAllocation      = dedicatedRequirements.requiresDedicatedAllocation;
599
600                 TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation));
601                 // Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false
602                 TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE);
603         }
604         else
605         {
606                 m_currentTestRequirements                                       = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
607                 m_currentTestPrefersDedicatedAllocation         = dedicatedRequirements.prefersDedicatedAllocation;
608                 m_currentTestRequiresDedicatedAllocation        = dedicatedRequirements.requiresDedicatedAllocation;
609         }
610 }
611
612 void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&                                       result,
613                                                                                                                                                         const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
614                                                                                                                                                         const VkPhysicalDeviceLimits&                   limits,
615                                                                                                                                                         const VkBufferCreateFlags                               bufferFlags,
616                                                                                                                                                         const VkBufferUsageFlags                                usage)
617 {
618         BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage);
619
620         result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
621                 "Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation");
622
623         result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
624                 "Regular (non-shared) objects must not require dedicated allocations");
625
626         result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
627                 "Preferred and required flags for dedicated memory cannot be set to true at the same time");
628 }
629
630
631 struct ImageTestParams
632 {
633         VkImageCreateFlags              flags;
634         VkImageTiling                   tiling;
635         bool                                    transient;
636 };
637
638 class IImageMemoryRequirements
639 {
640 public:
641         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group) = 0;
642
643 protected:
644         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
645                                                                                          const std::string&                                                     name,
646                                                                                          const std::string&                                                     desc,
647                                                                                          const ImageTestParams                                          arg0) = 0;
648
649         virtual tcu::TestStatus execTest                (Context&                                                                       context,
650                                                                                          const ImageTestParams                                          bufferFlags) = 0;
651
652         virtual void preTestChecks                              (Context&                                                                       context,
653                                                                                          const InstanceInterface&                                       vki,
654                                                                                          const VkPhysicalDevice                                         physDevice,
655                                                                                          const VkImageCreateFlags                                       flags) = 0;
656
657         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
658                                                                                          const VkDevice                                                         device) = 0;
659
660         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
661                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties) = 0;
662 };
663
664 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
665 {
666         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
667                                                                                          const ImageTestParams                                          params);
668
669 public:
670         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group);
671
672 protected:
673         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
674                                                                                          const std::string&                                                     name,
675                                                                                          const std::string&                                                     desc,
676                                                                                          const ImageTestParams                                          arg0);
677
678         virtual tcu::TestStatus execTest                (Context&                                                                       context,
679                                                                                          const ImageTestParams                                          params);
680
681         virtual void preTestChecks                              (Context&                                                                       context,
682                                                                                          const InstanceInterface&                                       vki,
683                                                                                          const VkPhysicalDevice                                         physDevice,
684                                                                                          const VkImageCreateFlags                                       flags);
685
686         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
687                                                                                          const VkDevice                                                         device);
688
689         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
690                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties);
691
692 private:
693         virtual bool isUsageMatchesFeatures             (const VkImageUsageFlags                                        usage,
694                                                                                          const VkFormatFeatureFlags                                     featureFlags);
695
696         virtual bool isImageSupported                   (const InstanceInterface&                                       vki,
697                                                                                          const VkPhysicalDevice                                         physDevice,
698                                                                                          const VkImageCreateInfo&                                       info);
699
700         virtual VkExtent3D makeExtentForImage   (const VkImageType                                                      imageType);
701
702         virtual bool isFormatMatchingAspect             (const VkFormat                                                         format,
703                                                                                          const VkImageAspectFlags                                       aspect);
704
705
706         virtual std::string getImageInfoString  (const VkImageCreateInfo&                                       imageInfo);
707
708 protected:
709         VkImageCreateInfo               m_currentTestImageInfo;
710         VkMemoryRequirements    m_currentTestRequirements;
711 };
712
713
714 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
715 {
716         ImageMemoryRequirementsOriginal test;
717
718         return test.execTest(context, params);
719 }
720
721 void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
722 {
723         const struct
724         {
725                 VkImageCreateFlags              flags;
726                 bool                                    transient;
727                 const char* const               name;
728         } imageFlagsCases[] =
729         {
730                 { (VkImageCreateFlags)0,                                                                                                                                                                                                false,  "regular"                                       },
731                 { (VkImageCreateFlags)0,                                                                                                                                                                                                true,   "transient"                                     },
732                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                   false,  "sparse"                                        },
733                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,                                                                                    false,  "sparse_residency"                      },
734                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT                                                                                    | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_aliased"                        },
735                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT             | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_residency_aliased"      },
736         };
737
738         de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", ""));
739
740         for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
741         for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
742         {
743                 ImageTestParams         params;
744                 std::ostringstream      caseName;
745
746                 params.flags            =  imageFlagsCases[flagsNdx].flags;
747                 params.transient        =  imageFlagsCases[flagsNdx].transient;
748                 caseName                        << imageFlagsCases[flagsNdx].name;
749
750                 if (tilingNdx != 0)
751                 {
752                         params.tiling =  VK_IMAGE_TILING_OPTIMAL;
753                         caseName      << "_tiling_optimal";
754                 }
755                 else
756                 {
757                         params.tiling =  VK_IMAGE_TILING_LINEAR;
758                         caseName      << "_tiling_linear";
759                 }
760
761                 if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
762                         continue;
763
764                 addFunctionTestCase(imageGroup.get(), caseName.str(), "", params);
765         }
766
767         group->addChild(imageGroup.release());
768 }
769
770 void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*          group,
771                                                                                                                    const std::string&           name,
772                                                                                                                    const std::string&           desc,
773                                                                                                                    const ImageTestParams        arg0)
774 {
775         addFunctionCase(group, name, desc, testEntryPoint, arg0);
776 }
777
778 void ImageMemoryRequirementsOriginal::preTestChecks (Context&                                   ,
779                                                                                                          const InstanceInterface&       vki,
780                                                                                                          const VkPhysicalDevice         physDevice,
781                                                                                                          const VkImageCreateFlags       createFlags)
782 {
783         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
784
785         if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
786                 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
787
788         if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
789                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
790
791         if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
792                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
793 }
794
795 void ImageMemoryRequirementsOriginal::updateMemoryRequirements  (const DeviceInterface&         vk,
796                                                                                                                                  const VkDevice                         device)
797 {
798         const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
799
800         m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
801 }
802
803 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&                                   result,
804                                                                                                                                 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties)
805 {
806         if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
807         {
808                 typedef std::vector<deUint32>::const_iterator   IndexIterator;
809                 const std::vector<deUint32>                                             usedMemoryTypeIndices                   = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
810                 bool                                                                                    deviceLocalMemoryFound                  = false;
811                 bool                                                                                    hostVisibleCoherentMemoryFound  = false;
812
813                 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
814                 {
815                         if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
816                         {
817                                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
818                                 continue;
819                         }
820
821                         const VkMemoryPropertyFlags     memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
822
823                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
824                                 deviceLocalMemoryFound = true;
825
826                         if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
827                                 hostVisibleCoherentMemoryFound = true;
828
829                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
830                         {
831                                 result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
832                                         "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
833                         }
834                 }
835
836                 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
837                         "VkMemoryRequirements alignment isn't power of two");
838
839                 result.check(deviceLocalMemoryFound,
840                         "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
841
842                 result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
843                         "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
844         }
845 }
846
847 bool ImageMemoryRequirementsOriginal::isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
848 {
849         if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
850                 return true;
851         if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
852                 return true;
853         if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
854                 return true;
855         if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
856                 return true;
857
858         return false;
859 }
860
861 //! This catches both invalid as well as legal but unsupported combinations of image parameters
862 bool ImageMemoryRequirementsOriginal::isImageSupported (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkImageCreateInfo& info)
863 {
864         DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
865
866         if (info.imageType == VK_IMAGE_TYPE_1D)
867         {
868                 DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
869         }
870         else if (info.imageType == VK_IMAGE_TYPE_2D)
871         {
872                 DE_ASSERT(info.extent.depth == 1u);
873
874                 if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
875                 {
876                         DE_ASSERT(info.extent.width == info.extent.height);
877                         DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
878                 }
879         }
880
881         if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
882                 return false;
883
884         if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
885                 (info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
886                 return false;
887
888         if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
889                 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
890                 return false;
891
892         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
893
894         if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
895         {
896                 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
897
898                 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
899                         return false;
900                 if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
901                         return false;
902                 if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
903                         return false;
904                 if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
905                         return false;
906                 if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
907                         return false;
908                 if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
909                         return false;
910                 if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
911                         return false;
912         }
913
914         if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
915                 return false;
916
917         switch (info.format)
918         {
919                 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
920                 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
921                 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
922                 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
923                 case VK_FORMAT_BC2_UNORM_BLOCK:
924                 case VK_FORMAT_BC2_SRGB_BLOCK:
925                 case VK_FORMAT_BC3_UNORM_BLOCK:
926                 case VK_FORMAT_BC3_SRGB_BLOCK:
927                 case VK_FORMAT_BC4_UNORM_BLOCK:
928                 case VK_FORMAT_BC4_SNORM_BLOCK:
929                 case VK_FORMAT_BC5_UNORM_BLOCK:
930                 case VK_FORMAT_BC5_SNORM_BLOCK:
931                 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
932                 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
933                 case VK_FORMAT_BC7_UNORM_BLOCK:
934                 case VK_FORMAT_BC7_SRGB_BLOCK:
935                         if (!features.textureCompressionBC)
936                                 return false;
937                         break;
938
939                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
940                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
941                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
942                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
943                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
944                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
945                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
946                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
947                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
948                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
949                         if (!features.textureCompressionETC2)
950                                 return false;
951                         break;
952
953                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
954                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
955                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
956                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
957                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
958                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
959                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
960                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
961                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
962                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
963                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
964                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
965                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
966                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
967                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
968                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
969                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
970                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
971                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
972                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
973                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
974                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
975                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
976                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
977                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
978                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
979                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
980                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
981                         if (!features.textureCompressionASTC_LDR)
982                                 return false;
983                         break;
984
985                 default:
986                         break;
987         }
988
989         const VkFormatProperties        formatProperties        = getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
990         const VkFormatFeatureFlags      formatFeatures          = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
991                                                                                                                                                                                          : formatProperties.optimalTilingFeatures);
992
993         if (!isUsageMatchesFeatures(info.usage, formatFeatures))
994                 return false;
995
996         VkImageFormatProperties         imageFormatProperties;
997         const VkResult                          result                          = vki.getPhysicalDeviceImageFormatProperties(
998                                                                                                                 physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
999
1000         if (result == VK_SUCCESS)
1001         {
1002                 if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1003                         return false;
1004                 if (info.mipLevels > imageFormatProperties.maxMipLevels)
1005                         return false;
1006                 if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1007                         return false;
1008         }
1009
1010         return result == VK_SUCCESS;
1011 }
1012
1013 VkExtent3D ImageMemoryRequirementsOriginal::makeExtentForImage (const VkImageType imageType)
1014 {
1015         VkExtent3D extent = { 64u, 64u, 4u };
1016
1017         if (imageType == VK_IMAGE_TYPE_1D)
1018                 extent.height = extent.depth = 1u;
1019         else if (imageType == VK_IMAGE_TYPE_2D)
1020                 extent.depth = 1u;
1021
1022         return extent;
1023 }
1024
1025 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
1026 {
1027         DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1028
1029         // D/S formats are laid out next to each other in the enum
1030         const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
1031
1032         return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
1033 }
1034
1035 std::string ImageMemoryRequirementsOriginal::getImageInfoString (const VkImageCreateInfo& imageInfo)
1036 {
1037         std::ostringstream str;
1038
1039         switch (imageInfo.imageType)
1040         {
1041                 case VK_IMAGE_TYPE_1D:                  str << "1D "; break;
1042                 case VK_IMAGE_TYPE_2D:                  str << "2D "; break;
1043                 case VK_IMAGE_TYPE_3D:                  str << "3D "; break;
1044                 default:                                                break;
1045         }
1046
1047         switch (imageInfo.tiling)
1048         {
1049                 case VK_IMAGE_TILING_OPTIMAL:   str << "(optimal) "; break;
1050                 case VK_IMAGE_TILING_LINEAR:    str << "(linear) "; break;
1051                 default:                                                break;
1052         }
1053
1054         str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
1055         str << imageInfo.format << " ";
1056         str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
1057         str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
1058         str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";
1059
1060         return str.str();
1061 }
1062
1063 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params)
1064 {
1065         const DeviceInterface&          vk                              = context.getDeviceInterface();
1066         const InstanceInterface&        vki                             = context.getInstanceInterface();
1067         const VkDevice                          device                  = context.getDevice();
1068         const VkPhysicalDevice          physDevice              = context.getPhysicalDevice();
1069         const VkImageCreateFlags        sparseFlags             = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1070         const VkImageUsageFlags         transientFlags  = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1071
1072         preTestChecks(context, vki, physDevice, params.flags);
1073
1074         const VkPhysicalDeviceMemoryProperties  memoryProperties                = getPhysicalDeviceMemoryProperties(vki, physDevice);
1075         const deUint32                                                  notInitializedBits              = ~0u;
1076         const VkImageAspectFlags                                colorAspect                             = VK_IMAGE_ASPECT_COLOR_BIT;
1077         const VkImageAspectFlags                                depthStencilAspect              = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1078         const VkImageAspectFlags                                allAspects[2]                   = { colorAspect, depthStencilAspect };
1079         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
1080         bool                                                                    allPass                                 = true;
1081         deUint32                                                                numCheckedImages                = 0u;
1082
1083         log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
1084
1085         for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
1086         {
1087                 const VkImageAspectFlags        aspect                                  = allAspects[loopAspectNdx];
1088                 deUint32                                        previousMemoryTypeBits  = notInitializedBits;
1089
1090                 for (VkFormat loopFormat = VK_FORMAT_R4G4_UNORM_PACK8; loopFormat <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; loopFormat = nextEnum(loopFormat))
1091                 if  (isFormatMatchingAspect(loopFormat, aspect))
1092                 {
1093                         // memoryTypeBits may differ between depth/stencil formats
1094                         if (aspect == depthStencilAspect)
1095                                 previousMemoryTypeBits = notInitializedBits;
1096
1097                         for (VkImageType                        loopImageType   = VK_IMAGE_TYPE_1D;                                     loopImageType   != VK_IMAGE_TYPE_LAST;                                  loopImageType   = nextEnum(loopImageType))
1098                         for (VkImageCreateFlags         loopCreateFlags = (VkImageCreateFlags)0;                        loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags))
1099                         for (VkImageUsageFlags          loopUsageFlags  = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;      loopUsageFlags  <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags  = nextFlagExcluding(loopUsageFlags, transientFlags))
1100                         for (VkSampleCountFlagBits      loopSampleCount = VK_SAMPLE_COUNT_1_BIT;                        loopSampleCount <= VK_SAMPLE_COUNT_16_BIT;                              loopSampleCount = nextFlag(loopSampleCount))
1101                         {
1102                                 const VkImageCreateFlags        actualCreateFlags       = loopCreateFlags | params.flags;
1103                                 const VkImageUsageFlags         actualUsageFlags        = loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1104                                 const bool                                      isCube                          = (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
1105                                 const VkImageCreateInfo         imageInfo                       =
1106                                 {
1107                                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
1108                                         DE_NULL,                                                                        // const void*              pNext;
1109                                         actualCreateFlags,                                                      // VkImageCreateFlags       flags;
1110                                         loopImageType,                                                          // VkImageType              imageType;
1111                                         loopFormat,                                                                     // VkFormat                 format;
1112                                         makeExtentForImage(loopImageType),                      // VkExtent3D               extent;
1113                                         1u,                                                                                     // uint32_t                 mipLevels;
1114                                         (isCube ? 6u : 1u),                                                     // uint32_t                 arrayLayers;
1115                                         loopSampleCount,                                                        // VkSampleCountFlagBits    samples;
1116                                         params.tiling,                                                          // VkImageTiling            tiling;
1117                                         actualUsageFlags,                                                       // VkImageUsageFlags        usage;
1118                                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
1119                                         0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
1120                                         DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
1121                                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
1122                                 };
1123
1124                                 m_currentTestImageInfo = imageInfo;
1125
1126                                 if (!isImageSupported(vki, physDevice, m_currentTestImageInfo))
1127                                         continue;
1128
1129                                 log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage;
1130                                 ++numCheckedImages;
1131
1132                                 tcu::ResultCollector result(log, "ERROR: ");
1133
1134                                 updateMemoryRequirements(vk, device);
1135
1136                                 verifyMemoryRequirements(result, memoryProperties);
1137
1138                                 // For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1139                                 result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1140                                                                 "memoryTypeBits differ from the ones in the previous image configuration");
1141
1142                                 if (result.getResult() != QP_TEST_RESULT_PASS)
1143                                         allPass = false;
1144
1145                                 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1146                         }
1147                 }
1148         }
1149
1150         if (numCheckedImages == 0u)
1151                 log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;
1152
1153         return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1154 }
1155
1156
1157 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1158 {
1159 public:
1160         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
1161                                                                                          const ImageTestParams                                          params);
1162
1163 protected:
1164         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
1165                                                                                          const std::string&                                                     name,
1166                                                                                          const std::string&                                                     desc,
1167                                                                                          const ImageTestParams                                          arg0);
1168
1169         virtual void preTestChecks                              (Context&                                                                       context,
1170                                                                                          const InstanceInterface&                                       vki,
1171                                                                                          const VkPhysicalDevice                                         physDevice,
1172                                                                                          const VkImageCreateFlags                                       flags);
1173
1174         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
1175                                                                                          const VkDevice                                                         device);
1176 };
1177
1178
1179 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
1180 {
1181         ImageMemoryRequirementsExtended test;
1182
1183         return test.execTest(context, params);
1184 }
1185
1186 void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*          group,
1187                                                                                                                    const std::string&           name,
1188                                                                                                                    const std::string&           desc,
1189                                                                                                                    const ImageTestParams        arg0)
1190 {
1191         addFunctionCase(group, name, desc, testEntryPoint, arg0);
1192 }
1193
1194 void ImageMemoryRequirementsExtended::preTestChecks (Context&                                   context,
1195                                                                                                          const InstanceInterface&       vki,
1196                                                                                                          const VkPhysicalDevice         physDevice,
1197                                                                                                          const VkImageCreateFlags       createFlags)
1198 {
1199         const std::string extensionName("VK_KHR_get_memory_requirements2");
1200
1201         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1202                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1203
1204         ImageMemoryRequirementsOriginal::preTestChecks (context, vki, physDevice, createFlags);
1205 }
1206
1207 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&          vk,
1208                                                                                                                             const VkDevice                              device)
1209 {
1210         m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1211 }
1212
1213
1214 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
1215 {
1216 public:
1217         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
1218                                                                                          const ImageTestParams                                          params);
1219
1220 protected:
1221         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
1222                                                                                          const std::string&                                                     name,
1223                                                                                          const std::string&                                                     desc,
1224                                                                                          const ImageTestParams                                          arg0);
1225
1226         virtual void preTestChecks                              (Context&                                                                       context,
1227                                                                                          const InstanceInterface&                                       vki,
1228                                                                                          const VkPhysicalDevice                                         physDevice,
1229                                                                                          const VkImageCreateFlags                                       flags);
1230
1231         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
1232                                                                                          const VkDevice                                                         device);
1233
1234         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
1235                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties);
1236
1237 protected:
1238         VkBool32        m_currentTestPrefersDedicatedAllocation;
1239         VkBool32        m_currentTestRequiresDedicatedAllocation;
1240 };
1241
1242
1243 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params)
1244 {
1245         ImageMemoryRequirementsDedicatedAllocation test;
1246
1247         return test.execTest(context, params);
1248 }
1249
1250 void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*               group,
1251                                                                                                                                           const std::string&            name,
1252                                                                                                                                           const std::string&            desc,
1253                                                                                                                                           const ImageTestParams         arg0)
1254 {
1255         addFunctionCase(group, name, desc, testEntryPoint, arg0);
1256 }
1257
1258 void ImageMemoryRequirementsDedicatedAllocation::preTestChecks (Context&                                        context,
1259                                                                                                                                 const InstanceInterface&        vki,
1260                                                                                                                                 const VkPhysicalDevice          physDevice,
1261                                                                                                                                 const VkImageCreateFlags        createFlags)
1262 {
1263         const std::string extensionName("VK_KHR_dedicated_allocation");
1264
1265         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1266                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1267
1268         ImageMemoryRequirementsExtended::preTestChecks (context, vki, physDevice, createFlags);
1269 }
1270
1271
1272 void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&       vk,
1273                                                                                                                                                    const VkDevice                       device)
1274 {
1275         const deUint32                                          invalidVkBool32                 = static_cast<deUint32>(~0);
1276
1277         VkMemoryDedicatedRequirementsKHR        dedicatedRequirements   =
1278         {
1279                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,    // VkStructureType      sType
1280                 DE_NULL,                                                                                                // void*                        pNext
1281                 invalidVkBool32,                                                                                // VkBool32                     prefersDedicatedAllocation
1282                 invalidVkBool32                                                                                 // VkBool32                     requiresDedicatedAllocation
1283         };
1284
1285         m_currentTestRequirements                                       = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements);
1286         m_currentTestPrefersDedicatedAllocation         = dedicatedRequirements.prefersDedicatedAllocation;
1287         m_currentTestRequiresDedicatedAllocation        = dedicatedRequirements.requiresDedicatedAllocation;
1288 }
1289
1290 void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&                                                result,
1291                                                                                                                                                    const VkPhysicalDeviceMemoryProperties&      deviceMemoryProperties)
1292 {
1293         ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties);
1294
1295         result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
1296                 "Non-bool value in m_currentTestPrefersDedicatedAllocation");
1297
1298         result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
1299                 "Test design expects m_currentTestRequiresDedicatedAllocation to be false");
1300
1301         result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
1302                 "Preferred and required flags for dedicated memory cannot be set to true at the same time");
1303 }
1304
1305 void populateCoreTestGroup (tcu::TestCaseGroup* group)
1306 {
1307         BufferMemoryRequirementsOriginal        bufferTest;
1308         ImageMemoryRequirementsOriginal         imageTest;
1309
1310         bufferTest.populateTestGroup(group);
1311         imageTest.populateTestGroup(group);
1312 }
1313
1314 void populateExtendedTestGroup (tcu::TestCaseGroup* group)
1315 {
1316         BufferMemoryRequirementsExtended        bufferTest;
1317         ImageMemoryRequirementsExtended         imageTest;
1318
1319         bufferTest.populateTestGroup(group);
1320         imageTest.populateTestGroup(group);
1321 }
1322
1323 void populateDedicatedAllocationTestGroup(tcu::TestCaseGroup* group)
1324 {
1325         BufferMemoryRequirementsDedicatedAllocation     bufferTest;
1326         ImageMemoryRequirementsDedicatedAllocation      imageTest;
1327
1328         bufferTest.populateTestGroup(group);
1329         imageTest.populateTestGroup(group);
1330 }
1331
1332 } // anonymous
1333
1334
1335 tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
1336 {
1337         de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements", "Buffer and image memory requirements"));
1338
1339         requirementsGroup->addChild(createTestGroup(testCtx, "core",                                    "Memory requirements tests with core functionality",                                            populateCoreTestGroup));
1340         requirementsGroup->addChild(createTestGroup(testCtx, "extended",                                "Memory requirements tests with extension VK_KHR_get_memory_requirements2",     populateExtendedTestGroup));
1341         requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation",    "Memory requirements tests with extension VK_KHR_dedicated_allocation",         populateDedicatedAllocationTestGroup));
1342
1343         return requirementsGroup.release();
1344 }
1345
1346 } // memory
1347 } // vkt