Merge changes Icb29d2da,Ida906e21 am: fc868645e2 am: 1cf9161f6f am: 12b6e41013
[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 class IBufferMemoryRequirements
153 {
154 public:
155         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group) = 0;
156
157 protected:
158         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
159                                                                                          const std::string&                                                     name,
160                                                                                          const std::string&                                                     desc,
161                                                                                          VkBufferCreateFlags                                            arg0) = 0;
162
163         virtual tcu::TestStatus execTest                (Context&                                                                       context,
164                                                                                          const VkBufferCreateFlags                                      bufferFlags) = 0;
165
166         virtual void preTestChecks                              (Context&                                                                       context,
167                                                                                          const InstanceInterface&                                       vki,
168                                                                                          const VkPhysicalDevice                                         physDevice,
169                                                                                          const VkBufferCreateFlags                                      flags) = 0;
170
171         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
172                                                                                          const VkDevice                                                         device,
173                                                                                          const VkDeviceSize                                                     size,
174                                                                                          const VkBufferCreateFlags                                      flags,
175                                                                                          const VkBufferUsageFlags                                       usage,
176                                                                                          const bool                                                                     all) = 0;
177
178         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
179                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
180                                                                                          const VkPhysicalDeviceLimits&                          limits,
181                                                                                          const VkBufferCreateFlags                                      bufferFlags,
182                                                                                          const VkBufferUsageFlags                                       usage) = 0;
183 };
184
185 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
186 {
187         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
188                                                                                          const VkBufferCreateFlags                                      bufferFlags);
189
190 public:
191         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group);
192
193 protected:
194         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
195                                                                                          const std::string&                                                     name,
196                                                                                          const std::string&                                                     desc,
197                                                                                          VkBufferCreateFlags                                            arg0);
198
199         virtual tcu::TestStatus execTest                (Context&                                                                       context,
200                                                                                          const VkBufferCreateFlags                                      bufferFlags);
201
202         virtual void preTestChecks                              (Context&                                                                       context,
203                                                                                          const InstanceInterface&                                       vki,
204                                                                                          const VkPhysicalDevice                                         physDevice,
205                                                                                          const VkBufferCreateFlags                                      flags);
206
207         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
208                                                                                          const VkDevice                                                         device,
209                                                                                          const VkDeviceSize                                                     size,
210                                                                                          const VkBufferCreateFlags                                      flags,
211                                                                                          const VkBufferUsageFlags                                       usage,
212                                                                                          const bool                                                                     all);
213
214         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
215                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
216                                                                                          const VkPhysicalDeviceLimits&                          limits,
217                                                                                          const VkBufferCreateFlags                                      bufferFlags,
218                                                                                          const VkBufferUsageFlags                                       usage);
219
220 protected:
221         VkMemoryRequirements    m_allUsageFlagsRequirements;
222         VkMemoryRequirements    m_currentTestRequirements;
223 };
224
225
226 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
227 {
228         BufferMemoryRequirementsOriginal test;
229
230         return test.execTest(context, bufferFlags);
231 }
232
233 void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
234 {
235         const struct
236         {
237                 VkBufferCreateFlags             flags;
238                 const char* const               name;
239         } bufferCases[] =
240         {
241                 { (VkBufferCreateFlags)0,                                                                                                                                                                                               "regular"                                       },
242                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                  "sparse"                                        },
243                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,                                                                                  "sparse_residency"                      },
244                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT                                                                                   | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,  "sparse_aliased"                        },
245                 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT   | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,  "sparse_residency_aliased"      },
246         };
247
248         de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", ""));
249
250         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
251                 addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, "", bufferCases[ndx].flags);
252
253         group->addChild(bufferGroup.release());
254 }
255
256 void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group,
257                                                                                                                         const std::string&      name,
258                                                                                                                         const std::string&      desc,
259                                                                                                                         VkBufferCreateFlags     arg0)
260 {
261         addFunctionCase(group, name, desc, testEntryPoint, arg0);
262 }
263
264 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags)
265 {
266         const DeviceInterface&                                  vk                      = context.getDeviceInterface();
267         const InstanceInterface&                                vki                     = context.getInstanceInterface();
268         const VkDevice                                                  device          = context.getDevice();
269         const VkPhysicalDevice                                  physDevice      = context.getPhysicalDevice();
270
271         preTestChecks(context, vki, physDevice, bufferFlags);
272
273         const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vki, physDevice);
274         const VkPhysicalDeviceLimits                    limits                          = getPhysicalDeviceProperties(vki, physDevice).limits;
275         const VkBufferUsageFlags                                allUsageFlags           = static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
276         tcu::TestLog&                                                   log                                     = context.getTestContext().getLog();
277         bool                                                                    allPass                         = true;
278
279         const VkDeviceSize sizeCases[] =
280         {
281                 1    * 1024,
282                 8    * 1024,
283                 64   * 1024,
284                 1024 * 1024,
285         };
286
287         // Updates m_allUsageFlags* fields
288         updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
289
290         for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
291         {
292                 deUint32                previousMemoryTypeBits  = 0u;
293                 VkDeviceSize    previousAlignment               = 0u;
294
295                 log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;
296
297                 for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
298                 {
299                         log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
300
301                         tcu::ResultCollector result(log, "ERROR: ");
302
303                         // Updates m_allUsageFlags* fields
304                         updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
305
306                         // Check:
307                         // - requirements for a particular buffer usage
308                         // - memoryTypeBits are a subset of bits for requirements with all usage flags combined
309                         verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
310
311                         // Check that for the same usage and create flags:
312                         // - memoryTypeBits are the same
313                         // - alignment is the same
314                         if (pSize > sizeCases)
315                         {
316                                 result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
317                                         "memoryTypeBits differ from the ones in the previous buffer size");
318
319                                 result.check(m_currentTestRequirements.alignment == previousAlignment,
320                                         "alignment differs from the one in the previous buffer size");
321                         }
322
323                         if (result.getResult() != QP_TEST_RESULT_PASS)
324                                 allPass = false;
325
326                         previousMemoryTypeBits  = m_currentTestRequirements.memoryTypeBits;
327                         previousAlignment               = m_currentTestRequirements.alignment;
328                 }
329
330                 if (!allPass)
331                         break;
332         }
333
334         return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
335 }
336
337 void BufferMemoryRequirementsOriginal::preTestChecks (Context&                                                          ,
338                                                                                                           const InstanceInterface&                              vki,
339                                                                                                           const VkPhysicalDevice                                physDevice,
340                                                                                                           const VkBufferCreateFlags                             flags)
341 {
342         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
343
344         if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
345                 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
346
347         if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer)
348                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer");
349
350         if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
351                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
352 }
353
354 void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface&         vk,
355                                                                                                                                  const VkDevice                         device,
356                                                                                                                                  const VkDeviceSize                     size,
357                                                                                                                                  const VkBufferCreateFlags      flags,
358                                                                                                                                  const VkBufferUsageFlags       usage,
359                                                                                                                                  const bool                                     all)
360 {
361         if (all)
362         {
363                 m_allUsageFlagsRequirements     = getBufferMemoryRequirements(vk, device, size, flags, usage);
364         }
365         else
366         {
367                 m_currentTestRequirements       = getBufferMemoryRequirements(vk, device, size, flags, usage);
368         }
369 }
370
371 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&                                          result,
372                                                                                                                                  const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties,
373                                                                                                                                  const VkPhysicalDeviceLimits&                          limits,
374                                                                                                                                  const VkBufferCreateFlags                                      bufferFlags,
375                                                                                                                                  const VkBufferUsageFlags                                       usage)
376 {
377         if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
378         {
379                 typedef std::vector<deUint32>::const_iterator   IndexIterator;
380                 const std::vector<deUint32>                                             usedMemoryTypeIndices                   = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
381                 bool                                                                                    deviceLocalMemoryFound                  = false;
382                 bool                                                                                    hostVisibleCoherentMemoryFound  = false;
383
384                 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
385                 {
386                         if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
387                         {
388                                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
389                                 continue;
390                         }
391
392                         const VkMemoryPropertyFlags     memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
393
394                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
395                                 deviceLocalMemoryFound = true;
396
397                         if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
398                                 hostVisibleCoherentMemoryFound = true;
399
400                         result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
401                                 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
402                 }
403
404                 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
405                         "VkMemoryRequirements alignment isn't power of two");
406
407                 if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
408                 {
409                         result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
410                                 "VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
411                 }
412
413                 if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
414                 {
415                         result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
416                                 "VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
417                 }
418
419                 if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
420                 {
421                         result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
422                                 "VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
423                 }
424
425                 result.check(deviceLocalMemoryFound,
426                         "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
427
428                 result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
429                         "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
430
431                 result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits,
432                         "Memory type bits aren't a superset of memory type bits for all usage flags combined");
433         }
434 }
435
436 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
437 {
438         static tcu::TestStatus testEntryPoint   (Context&                                       context,
439                                                                                          const VkBufferCreateFlags      bufferFlags);
440
441 protected:
442         virtual void addFunctionTestCase                (tcu::TestCaseGroup*            group,
443                                                                                          const std::string&                     name,
444                                                                                          const std::string&                     desc,
445                                                                                          VkBufferCreateFlags            arg0);
446
447         virtual void preTestChecks                              (Context&                                       context,
448                                                                                          const InstanceInterface&       vki,
449                                                                                          const VkPhysicalDevice         physDevice,
450                                                                                          const VkBufferCreateFlags      flags);
451
452         virtual void updateMemoryRequirements   (const DeviceInterface&         vk,
453                                                                                          const VkDevice                         device,
454                                                                                          const VkDeviceSize                     size,
455                                                                                          const VkBufferCreateFlags      flags,
456                                                                                          const VkBufferUsageFlags       usage,
457                                                                                          const bool                                     all);
458 };
459
460 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
461 {
462         BufferMemoryRequirementsExtended test;
463
464         return test.execTest(context, bufferFlags);
465 }
466
467 void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group,
468                                                                                                                         const std::string&      name,
469                                                                                                                         const std::string&      desc,
470                                                                                                                         VkBufferCreateFlags     arg0)
471 {
472         addFunctionCase(group, name, desc, testEntryPoint, arg0);
473 }
474
475 void BufferMemoryRequirementsExtended::preTestChecks (Context&                                  context,
476                                                                                                           const InstanceInterface&      vki,
477                                                                                                           const VkPhysicalDevice        physDevice,
478                                                                                                           const VkBufferCreateFlags     flags)
479 {
480         const std::string extensionName("VK_KHR_get_memory_requirements2");
481
482         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
483                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
484
485         BufferMemoryRequirementsOriginal::preTestChecks(context, vki, physDevice, flags);
486 }
487
488 void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&         vk,
489                                                                                                                                  const VkDevice                         device,
490                                                                                                                                  const VkDeviceSize                     size,
491                                                                                                                                  const VkBufferCreateFlags      flags,
492                                                                                                                                  const VkBufferUsageFlags       usage,
493                                                                                                                                  const bool                                     all)
494 {
495         if (all)
496         {
497                 m_allUsageFlagsRequirements     = getBufferMemoryRequirements2(vk, device, size, flags, usage);
498         }
499         else
500         {
501                 m_currentTestRequirements       = getBufferMemoryRequirements2(vk, device, size, flags, usage);
502         }
503 }
504
505
506
507 struct ImageTestParams
508 {
509         VkImageCreateFlags              flags;
510         VkImageTiling                   tiling;
511         bool                                    transient;
512 };
513
514 class IImageMemoryRequirements
515 {
516 public:
517         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group) = 0;
518
519 protected:
520         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
521                                                                                          const std::string&                                                     name,
522                                                                                          const std::string&                                                     desc,
523                                                                                          const ImageTestParams                                          arg0) = 0;
524
525         virtual tcu::TestStatus execTest                (Context&                                                                       context,
526                                                                                          const ImageTestParams                                          bufferFlags) = 0;
527
528         virtual void preTestChecks                              (Context&                                                                       context,
529                                                                                          const InstanceInterface&                                       vki,
530                                                                                          const VkPhysicalDevice                                         physDevice,
531                                                                                          const VkImageCreateFlags                                       flags) = 0;
532
533         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
534                                                                                          const VkDevice                                                         device) = 0;
535
536         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
537                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties) = 0;
538 };
539
540 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
541 {
542         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
543                                                                                          const ImageTestParams                                          params);
544
545 public:
546         virtual void populateTestGroup                  (tcu::TestCaseGroup*                                            group);
547
548 protected:
549         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
550                                                                                          const std::string&                                                     name,
551                                                                                          const std::string&                                                     desc,
552                                                                                          const ImageTestParams                                          arg0);
553
554         virtual tcu::TestStatus execTest                (Context&                                                                       context,
555                                                                                          const ImageTestParams                                          params);
556
557         virtual void preTestChecks                              (Context&                                                                       context,
558                                                                                          const InstanceInterface&                                       vki,
559                                                                                          const VkPhysicalDevice                                         physDevice,
560                                                                                          const VkImageCreateFlags                                       flags);
561
562         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
563                                                                                          const VkDevice                                                         device);
564
565         virtual void verifyMemoryRequirements   (tcu::ResultCollector&                                          result,
566                                                                                          const VkPhysicalDeviceMemoryProperties&        deviceMemoryProperties);
567
568 private:
569         virtual bool isUsageMatchesFeatures             (const VkImageUsageFlags                                        usage,
570                                                                                          const VkFormatFeatureFlags                                     featureFlags);
571
572         virtual bool isImageSupported                   (const InstanceInterface&                                       vki,
573                                                                                          const VkPhysicalDevice                                         physDevice,
574                                                                                          const VkImageCreateInfo&                                       info);
575
576         virtual VkExtent3D makeExtentForImage   (const VkImageType                                                      imageType);
577
578         virtual bool isFormatMatchingAspect             (const VkFormat                                                         format,
579                                                                                          const VkImageAspectFlags                                       aspect);
580
581
582         virtual std::string getImageInfoString  (const VkImageCreateInfo&                                       imageInfo);
583
584 protected:
585         VkImageCreateInfo               m_currentTestImageInfo;
586         VkMemoryRequirements    m_currentTestRequirements;
587 };
588
589
590 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
591 {
592         ImageMemoryRequirementsOriginal test;
593
594         return test.execTest(context, params);
595 }
596
597 void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
598 {
599         const struct
600         {
601                 VkImageCreateFlags              flags;
602                 bool                                    transient;
603                 const char* const               name;
604         } imageFlagsCases[] =
605         {
606                 { (VkImageCreateFlags)0,                                                                                                                                                                                                false,  "regular"                                       },
607                 { (VkImageCreateFlags)0,                                                                                                                                                                                                true,   "transient"                                     },
608                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT,                                                                                                                                                                   false,  "sparse"                                        },
609                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,                                                                                    false,  "sparse_residency"                      },
610                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT                                                                                    | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_aliased"                        },
611                 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT             | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,   false,  "sparse_residency_aliased"      },
612         };
613
614         de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", ""));
615
616         for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
617         for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
618         {
619                 ImageTestParams         params;
620                 std::ostringstream      caseName;
621
622                 params.flags            =  imageFlagsCases[flagsNdx].flags;
623                 params.transient        =  imageFlagsCases[flagsNdx].transient;
624                 caseName                        << imageFlagsCases[flagsNdx].name;
625
626                 if (tilingNdx != 0)
627                 {
628                         params.tiling =  VK_IMAGE_TILING_OPTIMAL;
629                         caseName      << "_tiling_optimal";
630                 }
631                 else
632                 {
633                         params.tiling =  VK_IMAGE_TILING_LINEAR;
634                         caseName      << "_tiling_linear";
635                 }
636
637                 if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
638                         continue;
639
640                 addFunctionTestCase(imageGroup.get(), caseName.str(), "", params);
641         }
642
643         group->addChild(imageGroup.release());
644 }
645
646 void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*          group,
647                                                                                                                    const std::string&           name,
648                                                                                                                    const std::string&           desc,
649                                                                                                                    const ImageTestParams        arg0)
650 {
651         addFunctionCase(group, name, desc, testEntryPoint, arg0);
652 }
653
654 void ImageMemoryRequirementsOriginal::preTestChecks (Context&                                   ,
655                                                                                                          const InstanceInterface&       vki,
656                                                                                                          const VkPhysicalDevice         physDevice,
657                                                                                                          const VkImageCreateFlags       createFlags)
658 {
659         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
660
661         if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
662                 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
663
664         if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
665                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
666
667         if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
668                 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
669 }
670
671 void ImageMemoryRequirementsOriginal::updateMemoryRequirements  (const DeviceInterface&         vk,
672                                                                                                                                  const VkDevice                         device)
673 {
674         const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
675
676         m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
677 }
678
679 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&                                   result,
680                                                                                                                                 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties)
681 {
682         if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
683         {
684                 typedef std::vector<deUint32>::const_iterator   IndexIterator;
685                 const std::vector<deUint32>                                             usedMemoryTypeIndices                   = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
686                 bool                                                                                    deviceLocalMemoryFound                  = false;
687                 bool                                                                                    hostVisibleCoherentMemoryFound  = false;
688
689                 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
690                 {
691                         if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
692                         {
693                                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
694                                 continue;
695                         }
696
697                         const VkMemoryPropertyFlags     memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
698
699                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
700                                 deviceLocalMemoryFound = true;
701
702                         if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
703                                 hostVisibleCoherentMemoryFound = true;
704
705                         if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
706                         {
707                                 result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
708                                         "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
709                         }
710                 }
711
712                 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
713                         "VkMemoryRequirements alignment isn't power of two");
714
715                 result.check(deviceLocalMemoryFound,
716                         "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
717
718                 result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
719                         "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
720         }
721 }
722
723 bool ImageMemoryRequirementsOriginal::isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
724 {
725         if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
726                 return true;
727         if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
728                 return true;
729         if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
730                 return true;
731         if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
732                 return true;
733
734         return false;
735 }
736
737 //! This catches both invalid as well as legal but unsupported combinations of image parameters
738 bool ImageMemoryRequirementsOriginal::isImageSupported (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkImageCreateInfo& info)
739 {
740         DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
741
742         if (info.imageType == VK_IMAGE_TYPE_1D)
743         {
744                 DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
745         }
746         else if (info.imageType == VK_IMAGE_TYPE_2D)
747         {
748                 DE_ASSERT(info.extent.depth == 1u);
749
750                 if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
751                 {
752                         DE_ASSERT(info.extent.width == info.extent.height);
753                         DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
754                 }
755         }
756
757         if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
758                 return false;
759
760         if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
761                 (info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
762                 return false;
763
764         if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
765                 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
766                 return false;
767
768         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
769
770         if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
771         {
772                 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
773
774                 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
775                         return false;
776                 if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
777                         return false;
778                 if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
779                         return false;
780                 if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
781                         return false;
782                 if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
783                         return false;
784                 if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
785                         return false;
786                 if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
787                         return false;
788         }
789
790         if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
791                 return false;
792
793         switch (info.format)
794         {
795                 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
796                 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
797                 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
798                 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
799                 case VK_FORMAT_BC2_UNORM_BLOCK:
800                 case VK_FORMAT_BC2_SRGB_BLOCK:
801                 case VK_FORMAT_BC3_UNORM_BLOCK:
802                 case VK_FORMAT_BC3_SRGB_BLOCK:
803                 case VK_FORMAT_BC4_UNORM_BLOCK:
804                 case VK_FORMAT_BC4_SNORM_BLOCK:
805                 case VK_FORMAT_BC5_UNORM_BLOCK:
806                 case VK_FORMAT_BC5_SNORM_BLOCK:
807                 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
808                 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
809                 case VK_FORMAT_BC7_UNORM_BLOCK:
810                 case VK_FORMAT_BC7_SRGB_BLOCK:
811                         if (!features.textureCompressionBC)
812                                 return false;
813                         break;
814
815                 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
816                 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
817                 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
818                 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
819                 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
820                 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
821                 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
822                 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
823                 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
824                 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
825                         if (!features.textureCompressionETC2)
826                                 return false;
827                         break;
828
829                 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
830                 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
831                 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
832                 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
833                 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
834                 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
835                 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
836                 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
837                 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
838                 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
839                 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
840                 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
841                 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
842                 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
843                 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
844                 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
845                 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
846                 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
847                 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
848                 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
849                 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
850                 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
851                 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
852                 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
853                 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
854                 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
855                 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
856                 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
857                         if (!features.textureCompressionASTC_LDR)
858                                 return false;
859                         break;
860
861                 default:
862                         break;
863         }
864
865         const VkFormatProperties        formatProperties        = getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
866         const VkFormatFeatureFlags      formatFeatures          = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
867                                                                                                                                                                                          : formatProperties.optimalTilingFeatures);
868
869         if (!isUsageMatchesFeatures(info.usage, formatFeatures))
870                 return false;
871
872         VkImageFormatProperties         imageFormatProperties;
873         const VkResult                          result                          = vki.getPhysicalDeviceImageFormatProperties(
874                                                                                                                 physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
875
876         if (result == VK_SUCCESS)
877         {
878                 if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
879                         return false;
880                 if (info.mipLevels > imageFormatProperties.maxMipLevels)
881                         return false;
882                 if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
883                         return false;
884         }
885
886         return result == VK_SUCCESS;
887 }
888
889 VkExtent3D ImageMemoryRequirementsOriginal::makeExtentForImage (const VkImageType imageType)
890 {
891         VkExtent3D extent = { 64u, 64u, 4u };
892
893         if (imageType == VK_IMAGE_TYPE_1D)
894                 extent.height = extent.depth = 1u;
895         else if (imageType == VK_IMAGE_TYPE_2D)
896                 extent.depth = 1u;
897
898         return extent;
899 }
900
901 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
902 {
903         DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
904
905         // D/S formats are laid out next to each other in the enum
906         const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
907
908         return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
909 }
910
911 std::string ImageMemoryRequirementsOriginal::getImageInfoString (const VkImageCreateInfo& imageInfo)
912 {
913         std::ostringstream str;
914
915         switch (imageInfo.imageType)
916         {
917                 case VK_IMAGE_TYPE_1D:                  str << "1D "; break;
918                 case VK_IMAGE_TYPE_2D:                  str << "2D "; break;
919                 case VK_IMAGE_TYPE_3D:                  str << "3D "; break;
920                 default:                                                break;
921         }
922
923         switch (imageInfo.tiling)
924         {
925                 case VK_IMAGE_TILING_OPTIMAL:   str << "(optimal) "; break;
926                 case VK_IMAGE_TILING_LINEAR:    str << "(linear) "; break;
927                 default:                                                break;
928         }
929
930         str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
931         str << imageInfo.format << " ";
932         str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
933         str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
934         str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";
935
936         return str.str();
937 }
938
939 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params)
940 {
941         const DeviceInterface&          vk                              = context.getDeviceInterface();
942         const InstanceInterface&        vki                             = context.getInstanceInterface();
943         const VkDevice                          device                  = context.getDevice();
944         const VkPhysicalDevice          physDevice              = context.getPhysicalDevice();
945         const VkImageCreateFlags        sparseFlags             = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
946         const VkImageUsageFlags         transientFlags  = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
947
948         preTestChecks(context, vki, physDevice, params.flags);
949
950         const VkPhysicalDeviceMemoryProperties  memoryProperties                = getPhysicalDeviceMemoryProperties(vki, physDevice);
951         const deUint32                                                  notInitializedBits              = ~0u;
952         const VkImageAspectFlags                                colorAspect                             = VK_IMAGE_ASPECT_COLOR_BIT;
953         const VkImageAspectFlags                                depthStencilAspect              = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
954         const VkImageAspectFlags                                allAspects[2]                   = { colorAspect, depthStencilAspect };
955         tcu::TestLog&                                                   log                                             = context.getTestContext().getLog();
956         bool                                                                    allPass                                 = true;
957         deUint32                                                                numCheckedImages                = 0u;
958
959         log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
960
961         for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
962         {
963                 const VkImageAspectFlags        aspect                                  = allAspects[loopAspectNdx];
964                 deUint32                                        previousMemoryTypeBits  = notInitializedBits;
965
966                 for (VkFormat loopFormat = VK_FORMAT_R4G4_UNORM_PACK8; loopFormat <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; loopFormat = nextEnum(loopFormat))
967                 if  (isFormatMatchingAspect(loopFormat, aspect))
968                 {
969                         // memoryTypeBits may differ between depth/stencil formats
970                         if (aspect == depthStencilAspect)
971                                 previousMemoryTypeBits = notInitializedBits;
972
973                         for (VkImageType                        loopImageType   = VK_IMAGE_TYPE_1D;                                     loopImageType   != VK_IMAGE_TYPE_LAST;                                  loopImageType   = nextEnum(loopImageType))
974                         for (VkImageCreateFlags         loopCreateFlags = (VkImageCreateFlags)0;                        loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags))
975                         for (VkImageUsageFlags          loopUsageFlags  = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;      loopUsageFlags  <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags  = nextFlagExcluding(loopUsageFlags, transientFlags))
976                         for (VkSampleCountFlagBits      loopSampleCount = VK_SAMPLE_COUNT_1_BIT;                        loopSampleCount <= VK_SAMPLE_COUNT_16_BIT;                              loopSampleCount = nextFlag(loopSampleCount))
977                         {
978                                 const VkImageCreateFlags        actualCreateFlags       = loopCreateFlags | params.flags;
979                                 const VkImageUsageFlags         actualUsageFlags        = loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
980                                 const bool                                      isCube                          = (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
981                                 const VkImageCreateInfo         imageInfo                       =
982                                 {
983                                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
984                                         DE_NULL,                                                                        // const void*              pNext;
985                                         actualCreateFlags,                                                      // VkImageCreateFlags       flags;
986                                         loopImageType,                                                          // VkImageType              imageType;
987                                         loopFormat,                                                                     // VkFormat                 format;
988                                         makeExtentForImage(loopImageType),                      // VkExtent3D               extent;
989                                         1u,                                                                                     // uint32_t                 mipLevels;
990                                         (isCube ? 6u : 1u),                                                     // uint32_t                 arrayLayers;
991                                         loopSampleCount,                                                        // VkSampleCountFlagBits    samples;
992                                         params.tiling,                                                          // VkImageTiling            tiling;
993                                         actualUsageFlags,                                                       // VkImageUsageFlags        usage;
994                                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
995                                         0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
996                                         DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
997                                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
998                                 };
999
1000                                 m_currentTestImageInfo = imageInfo;
1001
1002                                 if (!isImageSupported(vki, physDevice, m_currentTestImageInfo))
1003                                         continue;
1004
1005                                 log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage;
1006                                 ++numCheckedImages;
1007
1008                                 tcu::ResultCollector result(log, "ERROR: ");
1009
1010                                 updateMemoryRequirements(vk, device);
1011
1012                                 verifyMemoryRequirements(result, memoryProperties);
1013
1014                                 // For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1015                                 result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1016                                                                 "memoryTypeBits differ from the ones in the previous image configuration");
1017
1018                                 if (result.getResult() != QP_TEST_RESULT_PASS)
1019                                         allPass = false;
1020
1021                                 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1022                         }
1023                 }
1024         }
1025
1026         if (numCheckedImages == 0u)
1027                 log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;
1028
1029         return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1030 }
1031
1032
1033 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1034 {
1035 public:
1036         static tcu::TestStatus testEntryPoint   (Context&                                                                       context,
1037                                                                                          const ImageTestParams                                          params);
1038
1039 protected:
1040         virtual void addFunctionTestCase                (tcu::TestCaseGroup*                                            group,
1041                                                                                          const std::string&                                                     name,
1042                                                                                          const std::string&                                                     desc,
1043                                                                                          const ImageTestParams                                          arg0);
1044
1045         virtual void preTestChecks                              (Context&                                                                       context,
1046                                                                                          const InstanceInterface&                                       vki,
1047                                                                                          const VkPhysicalDevice                                         physDevice,
1048                                                                                          const VkImageCreateFlags                                       flags);
1049
1050         virtual void updateMemoryRequirements   (const DeviceInterface&                                         vk,
1051                                                                                          const VkDevice                                                         device);
1052 };
1053
1054
1055 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
1056 {
1057         ImageMemoryRequirementsExtended test;
1058
1059         return test.execTest(context, params);
1060 }
1061
1062 void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*          group,
1063                                                                                                                    const std::string&           name,
1064                                                                                                                    const std::string&           desc,
1065                                                                                                                    const ImageTestParams        arg0)
1066 {
1067         addFunctionCase(group, name, desc, testEntryPoint, arg0);
1068 }
1069
1070 void ImageMemoryRequirementsExtended::preTestChecks (Context&                                   context,
1071                                                                                                          const InstanceInterface&       vki,
1072                                                                                                          const VkPhysicalDevice         physDevice,
1073                                                                                                          const VkImageCreateFlags       createFlags)
1074 {
1075         const std::string extensionName("VK_KHR_get_memory_requirements2");
1076
1077         if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1078                 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1079
1080         ImageMemoryRequirementsOriginal::preTestChecks (context, vki, physDevice, createFlags);
1081 }
1082
1083 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&          vk,
1084                                                                                                                             const VkDevice                              device)
1085 {
1086         m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1087 }
1088
1089
1090 void populateCoreTestGroup (tcu::TestCaseGroup* group)
1091 {
1092         BufferMemoryRequirementsOriginal        bufferTest;
1093         ImageMemoryRequirementsOriginal         imageTest;
1094
1095         bufferTest.populateTestGroup(group);
1096         imageTest.populateTestGroup(group);
1097 }
1098
1099 void populateExtendedTestGroup (tcu::TestCaseGroup* group)
1100 {
1101         BufferMemoryRequirementsExtended        bufferTest;
1102         ImageMemoryRequirementsExtended         imageTest;
1103
1104         bufferTest.populateTestGroup(group);
1105         imageTest.populateTestGroup(group);
1106 }
1107
1108 } // anonymous
1109
1110
1111 tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
1112 {
1113         de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements", "Buffer and image memory requirements"));
1114
1115         requirementsGroup->addChild(createTestGroup(testCtx, "core",                                    "Memory requirements tests with core functionality",                                            populateCoreTestGroup));
1116         requirementsGroup->addChild(createTestGroup(testCtx, "extended",                                "Memory requirements tests with extension VK_KHR_get_memory_requirements2",     populateExtendedTestGroup));
1117
1118         return requirementsGroup.release();
1119 }
1120
1121 } // memory
1122 } // vkt