xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/memory/vktMemoryRequirementsTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Buffer and image memory requirements tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktMemoryRequirementsTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktTestGroupUtil.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkStrUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkImageUtil.hpp"
36 
37 #include "deUniquePtr.hpp"
38 #include "deStringUtil.hpp"
39 #include "deSTLUtil.hpp"
40 
41 #include "tcuResultCollector.hpp"
42 #include "tcuTestLog.hpp"
43 
44 #include <set>
45 
46 namespace vkt
47 {
48 namespace memory
49 {
50 namespace
51 {
52 using namespace vk;
53 using de::MovePtr;
54 using tcu::TestLog;
55 
makeBuffer(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage)56 Move<VkBuffer> makeBuffer(const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size,
57                           const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
58 {
59     const VkBufferCreateInfo createInfo = {
60         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType        sType;
61         DE_NULL,                              // const void*            pNext;
62         flags,                                // VkBufferCreateFlags    flags;
63         size,                                 // VkDeviceSize           size;
64         usage,                                // VkBufferUsageFlags     usage;
65         VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode          sharingMode;
66         0u,                                   // uint32_t               queueFamilyIndexCount;
67         DE_NULL,                              // const uint32_t*        pQueueFamilyIndices;
68     };
69     return createBuffer(vk, device, &createInfo);
70 }
71 
getBufferMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage)72 VkMemoryRequirements getBufferMemoryRequirements(const DeviceInterface &vk, const VkDevice device,
73                                                  const VkDeviceSize size, const VkBufferCreateFlags flags,
74                                                  const VkBufferUsageFlags usage)
75 {
76     const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
77     return getBufferMemoryRequirements(vk, device, *buffer);
78 }
79 
getBufferMemoryRequirements2(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,void * next=DE_NULL)80 VkMemoryRequirements getBufferMemoryRequirements2(const DeviceInterface &vk, const VkDevice device,
81                                                   const VkDeviceSize size, const VkBufferCreateFlags flags,
82                                                   const VkBufferUsageFlags usage, void *next = DE_NULL)
83 {
84     const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
85     VkBufferMemoryRequirementsInfo2 info = {
86         VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, // VkStructureType    sType
87         DE_NULL,                                             // const void*        pNext
88         *buffer                                              // VkBuffer            buffer
89     };
90     VkMemoryRequirements2 req2 = {
91         VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // VkStructureType        sType
92         next,                                    // void*                pNext
93         {0, 0, 0}                                // VkMemoryRequirements    memoryRequirements
94     };
95 
96     vk.getBufferMemoryRequirements2(device, &info, &req2);
97 
98     return req2.memoryRequirements;
99 }
100 
101 #ifndef CTS_USES_VULKANSC
getBufferCreateInfoMemoryRequirementsKHR(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,void * next=DE_NULL)102 VkMemoryRequirements getBufferCreateInfoMemoryRequirementsKHR(const DeviceInterface &vk, const VkDevice device,
103                                                               const VkDeviceSize size, const VkBufferCreateFlags flags,
104                                                               const VkBufferUsageFlags usage, void *next = DE_NULL)
105 {
106     const VkBufferCreateInfo createInfo = {
107         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType        sType;
108         DE_NULL,                              // const void*            pNext;
109         flags,                                // VkBufferCreateFlags    flags;
110         size,                                 // VkDeviceSize           size;
111         usage,                                // VkBufferUsageFlags     usage;
112         VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode          sharingMode;
113         0u,                                   // uint32_t               queueFamilyIndexCount;
114         DE_NULL,                              // const uint32_t*        pQueueFamilyIndices;
115     };
116     const VkDeviceBufferMemoryRequirementsKHR memoryInfo = {VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR,
117                                                             DE_NULL, &createInfo};
118     VkMemoryRequirements2 req2                           = {
119         VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType        sType
120         next,                                        // void*                pNext
121         {0, 0, 0} // VkMemoryRequirements    memoryRequirements
122     };
123 
124     vk.getDeviceBufferMemoryRequirements(device, &memoryInfo, &req2);
125 
126     return req2.memoryRequirements;
127 }
128 #endif // CTS_USES_VULKANSC
129 
getImageMemoryRequirements2(const DeviceInterface & vk,const VkDevice device,const VkImageCreateInfo & createInfo,void * next=DE_NULL)130 VkMemoryRequirements getImageMemoryRequirements2(const DeviceInterface &vk, const VkDevice device,
131                                                  const VkImageCreateInfo &createInfo, void *next = DE_NULL)
132 {
133     const Unique<VkImage> image(createImage(vk, device, &createInfo));
134 
135     VkImageMemoryRequirementsInfo2 info = {
136         VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, // VkStructureType    sType
137         DE_NULL,                                            // const void*        pNext
138         *image                                              // VkImage            image
139     };
140     VkMemoryRequirements2 req2 = {
141         VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // VkStructureType        sType
142         next,                                    // void*                pNext
143         {0, 0, 0}                                // VkMemoryRequirements    memoryRequirements
144     };
145 
146     vk.getImageMemoryRequirements2(device, &info, &req2);
147 
148     return req2.memoryRequirements;
149 }
150 
151 #ifndef CTS_USES_VULKANSC
getDeviceImageMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkImageCreateInfo & createInfo,void * next=DE_NULL)152 VkMemoryRequirements getDeviceImageMemoryRequirements(const DeviceInterface &vk, const VkDevice device,
153                                                       const VkImageCreateInfo &createInfo, void *next = DE_NULL)
154 {
155     VkDeviceImageMemoryRequirementsKHR info = {VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR, DE_NULL,
156                                                &createInfo, VkImageAspectFlagBits(0)};
157     VkMemoryRequirements2 req2              = {
158         VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType        sType
159         next,                                        // void*                pNext
160         {0, 0, 0}                                    // VkMemoryRequirements    memoryRequirements
161     };
162 
163     vk.getDeviceImageMemoryRequirements(device, &info, &req2);
164 
165     return req2.memoryRequirements;
166 }
167 #endif // CTS_USES_VULKANSC
168 
169 #ifndef CTS_USES_VULKANSC
getImageCreateInfoSparseMemoryRequirements(const DeviceInterface & vk,VkDevice device,const VkImageCreateInfo & createInfo)170 std::vector<VkSparseImageMemoryRequirements> getImageCreateInfoSparseMemoryRequirements(
171     const DeviceInterface &vk, VkDevice device, const VkImageCreateInfo &createInfo)
172 {
173     VkDeviceImageMemoryRequirementsKHR info = {VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR, DE_NULL,
174                                                &createInfo, VkImageAspectFlagBits(0)};
175     uint32_t requirementsCount              = 0;
176     std::vector<VkSparseImageMemoryRequirements> requirements;
177     std::vector<VkSparseImageMemoryRequirements2> requirements2;
178 
179     vk.getDeviceImageSparseMemoryRequirements(device, &info, &requirementsCount, DE_NULL);
180 
181     if (requirementsCount > 0)
182     {
183         requirements2.resize(requirementsCount);
184         for (uint32_t ndx = 0; ndx < requirementsCount; ++ndx)
185         {
186             requirements2[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2;
187             requirements2[ndx].pNext = DE_NULL;
188         }
189 
190         vk.getDeviceImageSparseMemoryRequirements(device, &info, &requirementsCount, &requirements2[0]);
191 
192         if ((size_t)requirementsCount != requirements2.size())
193             TCU_FAIL("Returned sparse image memory requirements count changes between queries");
194 
195         requirements.resize(requirementsCount);
196         for (uint32_t ndx = 0; ndx < requirementsCount; ++ndx)
197             requirements[ndx] = requirements2[ndx].memoryRequirements;
198     }
199 
200     return requirements;
201 }
202 #endif // CTS_USES_VULKANSC
203 
204 //! Get an index of each set bit, starting from the least significant bit.
bitsToIndices(uint32_t bits)205 std::vector<uint32_t> bitsToIndices(uint32_t bits)
206 {
207     std::vector<uint32_t> indices;
208     for (uint32_t i = 0u; bits != 0u; ++i, bits >>= 1)
209     {
210         if (bits & 1u)
211             indices.push_back(i);
212     }
213     return indices;
214 }
215 
216 template <typename T>
nextEnum(T value)217 T nextEnum(T value)
218 {
219     return static_cast<T>(static_cast<uint32_t>(value) + 1);
220 }
221 
222 template <typename T>
nextFlag(T value)223 T nextFlag(T value)
224 {
225     if (value)
226         return static_cast<T>(static_cast<uint32_t>(value) << 1);
227     else
228         return static_cast<T>(1);
229 }
230 
231 template <typename T>
nextFlagExcluding(T value,T excludedFlags)232 T nextFlagExcluding(T value, T excludedFlags)
233 {
234     uint32_t tmp = static_cast<uint32_t>(value);
235     while ((tmp = nextFlag(tmp)) & static_cast<uint32_t>(excludedFlags))
236         ;
237     return static_cast<T>(tmp);
238 }
239 
validValueVkBool32(const VkBool32 value)240 bool validValueVkBool32(const VkBool32 value)
241 {
242     return (value == VK_FALSE || value == VK_TRUE);
243 }
244 
245 class IBufferMemoryRequirements
246 {
247 public:
~IBufferMemoryRequirements()248     virtual ~IBufferMemoryRequirements()
249     {
250     }
251 
252     virtual void populateTestGroup(tcu::TestCaseGroup *group) = 0;
253 
254 protected:
255     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, VkBufferCreateFlags arg0) = 0;
256 
257     virtual tcu::TestStatus execTest(Context &context, const VkBufferCreateFlags bufferFlags) = 0;
258 
259     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size,
260                                           const VkBufferCreateFlags flags, const VkBufferUsageFlags usage,
261                                           const bool all) = 0;
262 
263     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
264                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
265                                           const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags,
266                                           const VkBufferUsageFlags usage) = 0;
267 };
268 
269 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
270 {
271     static tcu::TestStatus testEntryPoint(Context &context, const VkBufferCreateFlags bufferFlags);
272 
273 public:
274     virtual void populateTestGroup(tcu::TestCaseGroup *group);
275 
276 protected:
277     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, VkBufferCreateFlags arg0);
278 
279     virtual tcu::TestStatus execTest(Context &context, const VkBufferCreateFlags bufferFlags);
280 
281     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size,
282                                           const VkBufferCreateFlags flags, const VkBufferUsageFlags usage,
283                                           const bool all);
284 
285     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
286                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
287                                           const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags,
288                                           const VkBufferUsageFlags usage);
289 
290 protected:
291     VkMemoryRequirements m_allUsageFlagsRequirements;
292     VkMemoryRequirements m_currentTestRequirements;
293 };
294 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)295 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint(Context &context,
296                                                                  const VkBufferCreateFlags bufferFlags)
297 {
298     BufferMemoryRequirementsOriginal test;
299 
300     return test.execTest(context, bufferFlags);
301 }
302 
populateTestGroup(tcu::TestCaseGroup * group)303 void BufferMemoryRequirementsOriginal::populateTestGroup(tcu::TestCaseGroup *group)
304 {
305     const struct
306     {
307         VkBufferCreateFlags flags;
308         const char *const name;
309     } bufferCases[] = {
310         {(VkBufferCreateFlags)0, "regular"},
311 #ifndef CTS_USES_VULKANSC
312         {VK_BUFFER_CREATE_SPARSE_BINDING_BIT, "sparse"},
313         {VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, "sparse_residency"},
314         {VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, "sparse_aliased"},
315         {VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT |
316              VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,
317          "sparse_residency_aliased"},
318 #endif // CTS_USES_VULKANSC
319     };
320 
321     de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer"));
322 
323     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
324         addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, bufferCases[ndx].flags);
325 
326     group->addChild(bufferGroup.release());
327 }
328 
checkSupportBufferMemoryRequirementsOriginal(Context & context,VkBufferCreateFlags flags)329 void checkSupportBufferMemoryRequirementsOriginal(Context &context, VkBufferCreateFlags flags)
330 {
331     if (flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
332         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
333 
334     if (flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)
335         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER);
336 
337     if (flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
338         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
339 }
340 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)341 void BufferMemoryRequirementsOriginal::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
342                                                            VkBufferCreateFlags arg0)
343 {
344     addFunctionCase(group, name, checkSupportBufferMemoryRequirementsOriginal, testEntryPoint, arg0);
345 }
346 
execTest(Context & context,const VkBufferCreateFlags bufferFlags)347 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest(Context &context, const VkBufferCreateFlags bufferFlags)
348 {
349     const DeviceInterface &vk         = context.getDeviceInterface();
350     const InstanceInterface &vki      = context.getInstanceInterface();
351     const VkDevice device             = context.getDevice();
352     const VkPhysicalDevice physDevice = context.getPhysicalDevice();
353 
354     const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physDevice);
355     const VkPhysicalDeviceLimits limits                     = getPhysicalDeviceProperties(vki, physDevice).limits;
356     const VkBufferUsageFlags allUsageFlags =
357         static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
358     tcu::TestLog &log = context.getTestContext().getLog();
359     bool allPass      = true;
360 
361     const VkDeviceSize sizeCases[] = {
362         1 * 1024,
363         8 * 1024,
364         64 * 1024,
365         1024 * 1024,
366     };
367 
368     // Updates m_allUsageFlags* fields
369     updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
370 
371     for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
372          usage                    = nextFlag(usage))
373     {
374         uint32_t previousMemoryTypeBits = 0u;
375         VkDeviceSize previousAlignment  = 0u;
376 
377         log << tcu::TestLog::Message
378             << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage))
379             << tcu::TestLog::EndMessage;
380 
381         for (const VkDeviceSize *pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
382         {
383             log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
384 
385             tcu::ResultCollector result(log, "ERROR: ");
386 
387             // Updates m_allUsageFlags* fields
388             updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
389 
390             // Check:
391             // - requirements for a particular buffer usage
392             // - memoryTypeBits are a subset of bits for requirements with all usage flags combined
393             verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
394 
395             // Check that for the same usage and create flags:
396             // - memoryTypeBits are the same
397             // - alignment is the same
398             if (pSize > sizeCases)
399             {
400                 result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
401                              "memoryTypeBits differ from the ones in the previous buffer size");
402 
403                 result.check(m_currentTestRequirements.alignment == previousAlignment,
404                              "alignment differs from the one in the previous buffer size");
405             }
406 
407             if (result.getResult() != QP_TEST_RESULT_PASS)
408                 allPass = false;
409 
410             previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
411             previousAlignment      = m_currentTestRequirements.alignment;
412         }
413 
414         if (!allPass)
415             break;
416     }
417 
418     return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
419 }
420 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)421 void BufferMemoryRequirementsOriginal::updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device,
422                                                                 const VkDeviceSize size,
423                                                                 const VkBufferCreateFlags flags,
424                                                                 const VkBufferUsageFlags usage, const bool all)
425 {
426     if (all)
427     {
428         m_allUsageFlagsRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage);
429     }
430     else
431     {
432         m_currentTestRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage);
433     }
434 }
435 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkPhysicalDeviceLimits & limits,const VkBufferCreateFlags bufferFlags,const VkBufferUsageFlags usage)436 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements(
437     tcu::ResultCollector &result, const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
438     const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags, const VkBufferUsageFlags usage)
439 {
440     if (result.check(m_currentTestRequirements.memoryTypeBits != 0,
441                      "VkMemoryRequirements memoryTypeBits has no bits set"))
442     {
443         typedef std::vector<uint32_t>::const_iterator IndexIterator;
444         const std::vector<uint32_t> usedMemoryTypeIndices = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
445         bool deviceLocalMemoryFound                       = false;
446         bool hostVisibleCoherentMemoryFound               = false;
447 
448         for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end();
449              ++memoryTypeNdx)
450         {
451             if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
452             {
453                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
454                 continue;
455             }
456 
457             const VkMemoryPropertyFlags memoryPropertyFlags =
458                 deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
459 
460             if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
461                 deviceLocalMemoryFound = true;
462 
463             if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
464                 hostVisibleCoherentMemoryFound = true;
465 
466             result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
467                          "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
468         }
469 
470         result.check(deIsPowerOfTwo64(static_cast<uint64_t>(m_currentTestRequirements.alignment)) == true,
471                      "VkMemoryRequirements alignment isn't power of two");
472 
473         if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT))
474         {
475             result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
476                          "VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
477         }
478 
479         if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
480         {
481             result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
482                          "VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
483         }
484 
485         if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
486         {
487             result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
488                          "VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
489         }
490 
491         result.check(deviceLocalMemoryFound,
492                      "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
493 
494         result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
495                      "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and "
496                      "VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
497 
498         result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) ==
499                          m_allUsageFlagsRequirements.memoryTypeBits,
500                      "Memory type bits aren't a superset of memory type bits for all usage flags combined");
501     }
502 }
503 
504 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
505 {
506     static tcu::TestStatus testEntryPoint(Context &context, const VkBufferCreateFlags bufferFlags);
507 
508 protected:
509     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, VkBufferCreateFlags arg0);
510 
511     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size,
512                                           const VkBufferCreateFlags flags, const VkBufferUsageFlags usage,
513                                           const bool all);
514 };
515 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)516 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint(Context &context,
517                                                                  const VkBufferCreateFlags bufferFlags)
518 {
519     BufferMemoryRequirementsExtended test;
520 
521     return test.execTest(context, bufferFlags);
522 }
523 
checkSupportBufferMemoryRequirementsExtended(Context & context,VkBufferCreateFlags flags)524 void checkSupportBufferMemoryRequirementsExtended(Context &context, VkBufferCreateFlags flags)
525 {
526     checkSupportBufferMemoryRequirementsOriginal(context, flags);
527 
528     context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
529 }
530 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)531 void BufferMemoryRequirementsExtended::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
532                                                            VkBufferCreateFlags arg0)
533 {
534     addFunctionCase(group, name, checkSupportBufferMemoryRequirementsExtended, testEntryPoint, arg0);
535 }
536 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)537 void BufferMemoryRequirementsExtended::updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device,
538                                                                 const VkDeviceSize size,
539                                                                 const VkBufferCreateFlags flags,
540                                                                 const VkBufferUsageFlags usage, const bool all)
541 {
542     if (all)
543     {
544         m_allUsageFlagsRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage);
545     }
546     else
547     {
548         m_currentTestRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage);
549     }
550 }
551 
552 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
553 {
554     static tcu::TestStatus testEntryPoint(Context &context, const VkBufferCreateFlags bufferFlags);
555 
556 protected:
557     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, VkBufferCreateFlags arg0);
558 
559     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size,
560                                           const VkBufferCreateFlags flags, const VkBufferUsageFlags usage,
561                                           const bool all);
562 
563     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
564                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
565                                           const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags,
566                                           const VkBufferUsageFlags usage);
567 
568 protected:
569     VkBool32 m_allUsageFlagsPrefersDedicatedAllocation;
570     VkBool32 m_allUsageFlagsRequiresDedicatedAllocation;
571 
572     VkBool32 m_currentTestPrefersDedicatedAllocation;
573     VkBool32 m_currentTestRequiresDedicatedAllocation;
574 };
575 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)576 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context &context,
577                                                                             const VkBufferCreateFlags bufferFlags)
578 {
579     BufferMemoryRequirementsDedicatedAllocation test;
580 
581     return test.execTest(context, bufferFlags);
582 }
583 
checkSupportBufferMemoryRequirementsDedicatedAllocation(Context & context,VkBufferCreateFlags flags)584 void checkSupportBufferMemoryRequirementsDedicatedAllocation(Context &context, VkBufferCreateFlags flags)
585 {
586     checkSupportBufferMemoryRequirementsExtended(context, flags);
587 
588     context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
589 }
590 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)591 void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase(tcu::TestCaseGroup *group,
592                                                                       const std::string &name, VkBufferCreateFlags arg0)
593 {
594     addFunctionCase(group, name, checkSupportBufferMemoryRequirementsDedicatedAllocation, testEntryPoint, arg0);
595 }
596 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)597 void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements(
598     const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags,
599     const VkBufferUsageFlags usage, const bool all)
600 {
601     const uint32_t invalidVkBool32 = static_cast<uint32_t>(~0);
602 
603     VkMemoryDedicatedRequirements dedicatedRequirements = {
604         VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, // VkStructureType    sType
605         DE_NULL,                                         // void*            pNext
606         invalidVkBool32,                                 // VkBool32            prefersDedicatedAllocation
607         invalidVkBool32                                  // VkBool32            requiresDedicatedAllocation
608     };
609 
610     if (all)
611     {
612         m_allUsageFlagsRequirements =
613             getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
614         m_allUsageFlagsPrefersDedicatedAllocation  = dedicatedRequirements.prefersDedicatedAllocation;
615         m_allUsageFlagsRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation;
616 
617         TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation));
618         // Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false
619         TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE);
620     }
621     else
622     {
623         m_currentTestRequirements =
624             getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
625         m_currentTestPrefersDedicatedAllocation  = dedicatedRequirements.prefersDedicatedAllocation;
626         m_currentTestRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation;
627     }
628 }
629 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkPhysicalDeviceLimits & limits,const VkBufferCreateFlags bufferFlags,const VkBufferUsageFlags usage)630 void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements(
631     tcu::ResultCollector &result, const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
632     const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags, const VkBufferUsageFlags usage)
633 {
634     BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags,
635                                                                usage);
636 
637     result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
638                  "Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation");
639 
640     result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
641                  "Regular (non-shared) objects must not require dedicated allocations");
642 }
643 
644 #ifndef CTS_USES_VULKANSC
645 class BufferMemoryRequirementsCreateInfo : public BufferMemoryRequirementsOriginal
646 {
647     static tcu::TestStatus testEntryPoint(Context &context, const VkBufferCreateFlags bufferFlags);
648 
649 protected:
650     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, VkBufferCreateFlags arg0);
651 
652     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device, const VkDeviceSize size,
653                                           const VkBufferCreateFlags flags, const VkBufferUsageFlags usage,
654                                           const bool all);
655 
656     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
657                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
658                                           const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags,
659                                           const VkBufferUsageFlags usage);
660 
661 protected:
662     VkMemoryRequirements m_currentTestOriginalRequirements;
663     VkMemoryRequirements m_currentTestHalfRequirements;
664 };
665 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)666 tcu::TestStatus BufferMemoryRequirementsCreateInfo::testEntryPoint(Context &context,
667                                                                    const VkBufferCreateFlags bufferFlags)
668 {
669     BufferMemoryRequirementsCreateInfo test;
670 
671     return test.execTest(context, bufferFlags);
672 }
673 
checkSupportBufferMemoryRequirementsCreateInfo(Context & context,VkBufferCreateFlags flags)674 void checkSupportBufferMemoryRequirementsCreateInfo(Context &context, VkBufferCreateFlags flags)
675 {
676     checkSupportBufferMemoryRequirementsExtended(context, flags);
677 
678     context.requireDeviceFunctionality("VK_KHR_maintenance4");
679 }
680 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)681 void BufferMemoryRequirementsCreateInfo::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
682                                                              VkBufferCreateFlags arg0)
683 {
684     addFunctionCase(group, name, checkSupportBufferMemoryRequirementsCreateInfo, testEntryPoint, arg0);
685 }
686 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)687 void BufferMemoryRequirementsCreateInfo::updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device,
688                                                                   const VkDeviceSize size,
689                                                                   const VkBufferCreateFlags flags,
690                                                                   const VkBufferUsageFlags usage, const bool all)
691 {
692     if (all)
693     {
694         m_allUsageFlagsRequirements = getBufferCreateInfoMemoryRequirementsKHR(vk, device, size, flags, usage);
695     }
696     else
697     {
698         m_currentTestRequirements     = getBufferCreateInfoMemoryRequirementsKHR(vk, device, size, flags, usage);
699         m_currentTestHalfRequirements = getBufferCreateInfoMemoryRequirementsKHR(vk, device, size / 2, flags, usage);
700     }
701 
702     m_currentTestOriginalRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage);
703 }
704 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkPhysicalDeviceLimits & limits,const VkBufferCreateFlags bufferFlags,const VkBufferUsageFlags usage)705 void BufferMemoryRequirementsCreateInfo::verifyMemoryRequirements(
706     tcu::ResultCollector &result, const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties,
707     const VkPhysicalDeviceLimits &limits, const VkBufferCreateFlags bufferFlags, const VkBufferUsageFlags usage)
708 {
709     BufferMemoryRequirementsOriginal::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags,
710                                                                usage);
711 
712     result.check(m_currentTestRequirements.alignment == m_currentTestOriginalRequirements.alignment,
713                  "VkMemoryRequirements alignment queried from vkBufferCreateInfo does not match alignment from "
714                  "equivalent object");
715 
716     result.check(m_currentTestRequirements.memoryTypeBits == m_currentTestOriginalRequirements.memoryTypeBits,
717                  "VkMemoryRequirements memoryTypeBits queried from vkBufferCreateInfo does not match memoryTypeBits "
718                  "from equivalent object");
719 
720     result.check(
721         m_currentTestRequirements.size == m_currentTestOriginalRequirements.size,
722         "VkMemoryRequirements size queried from vkBufferCreateInfo does not match size from equivalent object");
723 
724     result.check(m_currentTestRequirements.size >= m_currentTestHalfRequirements.size,
725                  "VkMemoryRequirements size queried from vkBufferCreateInfo is larger for a smaller buffer");
726 }
727 #endif // CTS_USES_VULKANSC
728 
729 struct ImageTestParams
730 {
ImageTestParamsvkt::memory::__anon8c69ef220111::ImageTestParams731     ImageTestParams(VkImageCreateFlags flags_, VkImageTiling tiling_, bool transient_, bool useMaint4_ = false)
732         : flags(flags_)
733         , tiling(tiling_)
734         , transient(transient_)
735         , useMaint4(useMaint4_)
736     {
737     }
738 
ImageTestParamsvkt::memory::__anon8c69ef220111::ImageTestParams739     ImageTestParams(void)
740     {
741     }
742 
743     VkImageCreateFlags flags;
744     VkImageTiling tiling;
745     bool transient;
746     bool useMaint4;
747 };
748 
749 class IImageMemoryRequirements
750 {
751 public:
~IImageMemoryRequirements()752     virtual ~IImageMemoryRequirements()
753     {
754     }
755 
756     virtual void populateTestGroup(tcu::TestCaseGroup *group) = 0;
757 
758 protected:
759     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
760                                      const ImageTestParams arg0) = 0;
761 
762     virtual tcu::TestStatus execTest(Context &context, const ImageTestParams bufferFlags) = 0;
763 
764     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device) = 0;
765 
766     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
767                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties) = 0;
768 };
769 
770 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
771 {
772     static tcu::TestStatus testEntryPoint(Context &context, const ImageTestParams params);
773 
774 public:
775     virtual void populateTestGroup(tcu::TestCaseGroup *group);
776 
777 protected:
778     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, const ImageTestParams arg0);
779 
780     virtual tcu::TestStatus execTest(Context &context, const ImageTestParams params);
781 
782     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device);
783 
784     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
785                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties);
786 
787 private:
788     virtual bool isImageSupported(const Context &context, const InstanceInterface &vki,
789                                   const VkPhysicalDevice physDevice, const VkImageCreateInfo &info);
790 
791     virtual bool isFormatMatchingAspect(const VkFormat format, const VkImageAspectFlags aspect);
792 
793 protected:
794     VkImageCreateInfo m_currentTestImageInfo;
795     VkMemoryRequirements m_currentTestRequirements;
796 #ifndef CTS_USES_VULKANSC
797     std::vector<VkSparseImageMemoryRequirements> m_currentTestSparseRequirements;
798 #endif // CTS_USES_VULKANSC
799 };
800 
testEntryPoint(Context & context,const ImageTestParams params)801 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint(Context &context, const ImageTestParams params)
802 {
803     ImageMemoryRequirementsOriginal test;
804 
805     return test.execTest(context, params);
806 }
807 
populateTestGroup(tcu::TestCaseGroup * group)808 void ImageMemoryRequirementsOriginal::populateTestGroup(tcu::TestCaseGroup *group)
809 {
810     const struct
811     {
812         VkImageCreateFlags flags;
813         bool transient;
814         const char *const name;
815     } imageFlagsCases[] = {
816         {(VkImageCreateFlags)0, false, "regular"},
817         {(VkImageCreateFlags)0, true, "transient"},
818 #ifndef CTS_USES_VULKANSC
819         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT, false, "sparse"},
820         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, false, "sparse_residency"},
821         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_aliased"},
822         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
823          false, "sparse_residency_aliased"},
824 #endif // CTS_USES_VULKANSC
825     };
826 
827     de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image"));
828 
829     for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
830         for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
831         {
832             ImageTestParams params;
833             std::ostringstream caseName;
834 
835             params.flags     = imageFlagsCases[flagsNdx].flags;
836             params.transient = imageFlagsCases[flagsNdx].transient;
837             params.useMaint4 = false;
838             caseName << imageFlagsCases[flagsNdx].name;
839 
840             if (tilingNdx != 0)
841             {
842                 params.tiling = VK_IMAGE_TILING_OPTIMAL;
843                 caseName << "_tiling_optimal";
844             }
845             else
846             {
847                 params.tiling = VK_IMAGE_TILING_LINEAR;
848                 caseName << "_tiling_linear";
849             }
850 
851             if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
852                 continue;
853 
854             addFunctionTestCase(imageGroup.get(), caseName.str(), params);
855         }
856 
857     group->addChild(imageGroup.release());
858 }
859 
checkSupportImageMemoryRequirementsOriginal(Context & context,ImageTestParams params)860 void checkSupportImageMemoryRequirementsOriginal(Context &context, ImageTestParams params)
861 {
862     const VkPhysicalDeviceFeatures features =
863         getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
864 
865     if (params.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
866         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
867 
868     if (params.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
869         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
870 
871     if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) &&
872         !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
873         TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
874 }
875 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)876 void ImageMemoryRequirementsOriginal::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
877                                                           const ImageTestParams arg0)
878 {
879     addFunctionCase(group, name, checkSupportImageMemoryRequirementsOriginal, testEntryPoint, arg0);
880 }
881 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)882 void ImageMemoryRequirementsOriginal::updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device)
883 {
884     const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
885 
886     m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
887 
888 #ifndef CTS_USES_VULKANSC
889     if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
890         m_currentTestSparseRequirements = getImageSparseMemoryRequirements(vk, device, *image);
891 #endif // CTS_USES_VULKANSC
892 }
893 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties)894 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements(
895     tcu::ResultCollector &result, const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties)
896 {
897     if (result.check(m_currentTestRequirements.memoryTypeBits != 0,
898                      "VkMemoryRequirements memoryTypeBits has no bits set"))
899     {
900         typedef std::vector<uint32_t>::const_iterator IndexIterator;
901         const std::vector<uint32_t> usedMemoryTypeIndices = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
902         bool deviceLocalMemoryFound                       = false;
903         bool hostVisibleCoherentMemoryFound               = false;
904 
905         for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end();
906              ++memoryTypeNdx)
907         {
908             if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
909             {
910                 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
911                 continue;
912             }
913 
914             const VkMemoryPropertyFlags memoryPropertyFlags =
915                 deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
916 
917             if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
918                 deviceLocalMemoryFound = true;
919 
920             if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
921                 hostVisibleCoherentMemoryFound = true;
922 
923             if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
924             {
925                 result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
926                              "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient "
927                              "attachment image");
928             }
929         }
930 
931         result.check(deIsPowerOfTwo64(static_cast<uint64_t>(m_currentTestRequirements.alignment)) == true,
932                      "VkMemoryRequirements alignment isn't power of two");
933 
934         result.check(deviceLocalMemoryFound,
935                      "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
936 
937         result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
938                      "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and "
939                      "VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
940 
941 #ifndef CTS_USES_VULKANSC
942         if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
943         {
944             for (const VkSparseImageMemoryRequirements &sparseRequirements : m_currentTestSparseRequirements)
945             {
946                 result.check((sparseRequirements.imageMipTailSize % m_currentTestRequirements.alignment) == 0,
947                              "VkSparseImageMemoryRequirements imageMipTailSize is not aligned with sparse block size");
948             }
949         }
950 #endif // CTS_USES_VULKANSC
951     }
952 }
953 
isUsageMatchesFeatures(const VkImageUsageFlags usage,const VkFormatFeatureFlags featureFlags)954 bool isUsageMatchesFeatures(const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
955 {
956     if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
957         return true;
958     if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
959         return true;
960     if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) &&
961         (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
962         return true;
963     if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
964         (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
965         return true;
966 
967     return false;
968 }
969 
doesUsageSatisfyFeatures(const VkImageUsageFlags usage,const VkFormatFeatureFlags featureFlags)970 bool doesUsageSatisfyFeatures(const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
971 {
972     bool ans = true;
973 
974     if (usage & VK_IMAGE_USAGE_SAMPLED_BIT)
975         ans &= ((featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0);
976     if (usage & VK_IMAGE_USAGE_STORAGE_BIT)
977         ans &= ((featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0);
978     if (usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
979         ans &= ((featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0);
980     if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
981         ans &= ((featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0);
982 
983     return ans;
984 }
985 
986 //! This catches both invalid as well as legal but unsupported combinations of image parameters
isImageSupported(const Context & context,const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkImageCreateInfo & info)987 bool ImageMemoryRequirementsOriginal::isImageSupported(const Context &context, const InstanceInterface &vki,
988                                                        const VkPhysicalDevice physDevice, const VkImageCreateInfo &info)
989 {
990     DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
991 
992 #ifndef CTS_USES_VULKANSC
993     if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5"))
994     {
995         if (info.format == VK_FORMAT_A8_UNORM_KHR || info.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
996             return false;
997     }
998 #endif // CTS_USES_VULKANSC
999 
1000     if (isYCbCrFormat(info.format) && (info.imageType != VK_IMAGE_TYPE_2D || info.mipLevels != 1 ||
1001                                        info.arrayLayers != 1 || info.samples != VK_SAMPLE_COUNT_1_BIT ||
1002                                        !context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion")))
1003     {
1004         return false;
1005     }
1006 
1007     if (info.imageType == VK_IMAGE_TYPE_1D)
1008     {
1009         DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
1010     }
1011     else if (info.imageType == VK_IMAGE_TYPE_2D)
1012     {
1013         DE_ASSERT(info.extent.depth == 1u);
1014 
1015         if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
1016         {
1017             DE_ASSERT(info.extent.width == info.extent.height);
1018             DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
1019         }
1020     }
1021 
1022     if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
1023         return false;
1024 
1025     if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
1026         (info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ||
1027          info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
1028         return false;
1029 
1030     if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
1031         (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
1032                        VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
1033         return false;
1034 
1035     const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1036 
1037     if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
1038     {
1039         DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
1040 
1041         if (info.imageType == VK_IMAGE_TYPE_1D)
1042             return false;
1043 
1044         if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
1045             return false;
1046         if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
1047             return false;
1048         if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
1049             return false;
1050         if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
1051             return false;
1052         if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
1053             return false;
1054         if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
1055             return false;
1056         if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
1057             return false;
1058     }
1059 
1060     if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
1061         !features.shaderStorageImageMultisample)
1062         return false;
1063 
1064     switch (info.format)
1065     {
1066     case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
1067     case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
1068     case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
1069     case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
1070     case VK_FORMAT_BC2_UNORM_BLOCK:
1071     case VK_FORMAT_BC2_SRGB_BLOCK:
1072     case VK_FORMAT_BC3_UNORM_BLOCK:
1073     case VK_FORMAT_BC3_SRGB_BLOCK:
1074     case VK_FORMAT_BC4_UNORM_BLOCK:
1075     case VK_FORMAT_BC4_SNORM_BLOCK:
1076     case VK_FORMAT_BC5_UNORM_BLOCK:
1077     case VK_FORMAT_BC5_SNORM_BLOCK:
1078     case VK_FORMAT_BC6H_UFLOAT_BLOCK:
1079     case VK_FORMAT_BC6H_SFLOAT_BLOCK:
1080     case VK_FORMAT_BC7_UNORM_BLOCK:
1081     case VK_FORMAT_BC7_SRGB_BLOCK:
1082         if (!features.textureCompressionBC)
1083             return false;
1084         break;
1085 
1086     case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
1087     case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
1088     case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
1089     case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
1090     case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
1091     case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
1092     case VK_FORMAT_EAC_R11_UNORM_BLOCK:
1093     case VK_FORMAT_EAC_R11_SNORM_BLOCK:
1094     case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
1095     case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
1096         if (!features.textureCompressionETC2)
1097             return false;
1098         break;
1099 
1100     case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
1101     case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
1102     case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
1103     case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
1104     case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
1105     case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
1106     case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
1107     case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
1108     case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
1109     case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
1110     case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
1111     case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
1112     case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
1113     case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
1114     case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
1115     case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
1116     case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
1117     case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
1118     case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
1119     case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
1120     case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
1121     case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
1122     case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
1123     case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
1124     case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
1125     case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
1126     case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
1127     case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
1128         if (!features.textureCompressionASTC_LDR)
1129             return false;
1130         break;
1131 
1132     default:
1133         break;
1134     }
1135 
1136     const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
1137     const VkFormatFeatureFlags formatFeatures =
1138         (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures :
1139                                                  formatProperties.optimalTilingFeatures);
1140 
1141     if (!isUsageMatchesFeatures(info.usage, formatFeatures))
1142         return false;
1143 
1144     VkImageFormatProperties imageFormatProperties;
1145     const VkResult result = vki.getPhysicalDeviceImageFormatProperties(
1146         physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1147 
1148     if (result == VK_SUCCESS)
1149     {
1150         if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1151             return false;
1152         if (info.mipLevels > imageFormatProperties.maxMipLevels)
1153             return false;
1154         if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1155             return false;
1156     }
1157 
1158 #ifndef CTS_USES_VULKANSC
1159     if ((info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !checkSparseImageFormatSupport(physDevice, vki, info))
1160         return false;
1161 #endif // CTS_USES_VULKANSC
1162 
1163     return result == VK_SUCCESS;
1164 }
1165 
makeExtentForImage(const VkImageType imageType)1166 VkExtent3D makeExtentForImage(const VkImageType imageType)
1167 {
1168     VkExtent3D extent = {64u, 64u, 4u};
1169 
1170     if (imageType == VK_IMAGE_TYPE_1D)
1171         extent.height = extent.depth = 1u;
1172     else if (imageType == VK_IMAGE_TYPE_2D)
1173         extent.depth = 1u;
1174 
1175     return extent;
1176 }
1177 
1178 #ifndef CTS_USES_VULKANSC
halfExtentForImage(const VkImageType imageType,VkExtent3D extent)1179 VkExtent3D halfExtentForImage(const VkImageType imageType, VkExtent3D extent)
1180 {
1181     VkExtent3D halfExtent = extent;
1182 
1183     if (imageType == VK_IMAGE_TYPE_1D)
1184         halfExtent.width /= 2;
1185     else if (imageType == VK_IMAGE_TYPE_2D)
1186         halfExtent.height /= 2;
1187     else
1188         halfExtent.depth /= 2;
1189 
1190     return halfExtent;
1191 }
1192 #endif // CTS_USES_VULKANSC
1193 
isFormatMatchingAspect(const VkFormat format,const VkImageAspectFlags aspect)1194 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect(const VkFormat format, const VkImageAspectFlags aspect)
1195 {
1196     DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT ||
1197               aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1198 
1199     // D/S formats are laid out next to each other in the enum
1200     const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
1201 
1202     return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
1203 }
1204 
getImageInfoString(const VkImageCreateInfo & imageInfo)1205 std::string getImageInfoString(const VkImageCreateInfo &imageInfo)
1206 {
1207     std::ostringstream str;
1208 
1209     switch (imageInfo.imageType)
1210     {
1211     case VK_IMAGE_TYPE_1D:
1212         str << "1D ";
1213         break;
1214     case VK_IMAGE_TYPE_2D:
1215         str << "2D ";
1216         break;
1217     case VK_IMAGE_TYPE_3D:
1218         str << "3D ";
1219         break;
1220     default:
1221         break;
1222     }
1223 
1224     switch (imageInfo.tiling)
1225     {
1226     case VK_IMAGE_TILING_OPTIMAL:
1227         str << "(optimal) ";
1228         break;
1229     case VK_IMAGE_TILING_LINEAR:
1230         str << "(linear) ";
1231         break;
1232     default:
1233         break;
1234     }
1235 
1236     str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth
1237         << "] ";
1238     str << imageInfo.format << " ";
1239     str << "samples:" << static_cast<uint32_t>(imageInfo.samples) << " ";
1240     str << "flags:" << static_cast<uint32_t>(imageInfo.flags) << " ";
1241     str << "usage:" << static_cast<uint32_t>(imageInfo.usage) << " ";
1242 
1243     return str.str();
1244 }
1245 
execTest(Context & context,const ImageTestParams params)1246 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest(Context &context, const ImageTestParams params)
1247 {
1248     const VkFormat formats[] = {
1249         VK_FORMAT_R4G4_UNORM_PACK8,
1250         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1251         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1252         VK_FORMAT_R5G6B5_UNORM_PACK16,
1253         VK_FORMAT_B5G6R5_UNORM_PACK16,
1254         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1255         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1256         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1257 #ifndef CTS_USES_VULKANSC
1258         VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
1259 #endif // CTS_USES_VULKANSC
1260         VK_FORMAT_R8_UNORM,
1261         VK_FORMAT_R8_SNORM,
1262         VK_FORMAT_R8_USCALED,
1263         VK_FORMAT_R8_SSCALED,
1264         VK_FORMAT_R8_UINT,
1265         VK_FORMAT_R8_SINT,
1266         VK_FORMAT_R8_SRGB,
1267 #ifndef CTS_USES_VULKANSC
1268         VK_FORMAT_A8_UNORM_KHR,
1269 #endif // CTS_USES_VULKANSC
1270         VK_FORMAT_R8G8_UNORM,
1271         VK_FORMAT_R8G8_SNORM,
1272         VK_FORMAT_R8G8_USCALED,
1273         VK_FORMAT_R8G8_SSCALED,
1274         VK_FORMAT_R8G8_UINT,
1275         VK_FORMAT_R8G8_SINT,
1276         VK_FORMAT_R8G8_SRGB,
1277         VK_FORMAT_R8G8B8_UNORM,
1278         VK_FORMAT_R8G8B8_SNORM,
1279         VK_FORMAT_R8G8B8_USCALED,
1280         VK_FORMAT_R8G8B8_SSCALED,
1281         VK_FORMAT_R8G8B8_UINT,
1282         VK_FORMAT_R8G8B8_SINT,
1283         VK_FORMAT_R8G8B8_SRGB,
1284         VK_FORMAT_B8G8R8_UNORM,
1285         VK_FORMAT_B8G8R8_SNORM,
1286         VK_FORMAT_B8G8R8_USCALED,
1287         VK_FORMAT_B8G8R8_SSCALED,
1288         VK_FORMAT_B8G8R8_UINT,
1289         VK_FORMAT_B8G8R8_SINT,
1290         VK_FORMAT_B8G8R8_SRGB,
1291         VK_FORMAT_R8G8B8A8_UNORM,
1292         VK_FORMAT_R8G8B8A8_SNORM,
1293         VK_FORMAT_R8G8B8A8_USCALED,
1294         VK_FORMAT_R8G8B8A8_SSCALED,
1295         VK_FORMAT_R8G8B8A8_UINT,
1296         VK_FORMAT_R8G8B8A8_SINT,
1297         VK_FORMAT_R8G8B8A8_SRGB,
1298         VK_FORMAT_B8G8R8A8_UNORM,
1299         VK_FORMAT_B8G8R8A8_SNORM,
1300         VK_FORMAT_B8G8R8A8_USCALED,
1301         VK_FORMAT_B8G8R8A8_SSCALED,
1302         VK_FORMAT_B8G8R8A8_UINT,
1303         VK_FORMAT_B8G8R8A8_SINT,
1304         VK_FORMAT_B8G8R8A8_SRGB,
1305         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1306         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1307         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1308         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1309         VK_FORMAT_A8B8G8R8_UINT_PACK32,
1310         VK_FORMAT_A8B8G8R8_SINT_PACK32,
1311         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1312         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1313         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1314         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1315         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1316         VK_FORMAT_A2R10G10B10_UINT_PACK32,
1317         VK_FORMAT_A2R10G10B10_SINT_PACK32,
1318         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1319         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1320         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1321         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1322         VK_FORMAT_A2B10G10R10_UINT_PACK32,
1323         VK_FORMAT_A2B10G10R10_SINT_PACK32,
1324         VK_FORMAT_R16_UNORM,
1325         VK_FORMAT_R16_SNORM,
1326         VK_FORMAT_R16_USCALED,
1327         VK_FORMAT_R16_SSCALED,
1328         VK_FORMAT_R16_UINT,
1329         VK_FORMAT_R16_SINT,
1330         VK_FORMAT_R16_SFLOAT,
1331         VK_FORMAT_R16G16_UNORM,
1332         VK_FORMAT_R16G16_SNORM,
1333         VK_FORMAT_R16G16_USCALED,
1334         VK_FORMAT_R16G16_SSCALED,
1335         VK_FORMAT_R16G16_UINT,
1336         VK_FORMAT_R16G16_SINT,
1337         VK_FORMAT_R16G16_SFLOAT,
1338         VK_FORMAT_R16G16B16_UNORM,
1339         VK_FORMAT_R16G16B16_SNORM,
1340         VK_FORMAT_R16G16B16_USCALED,
1341         VK_FORMAT_R16G16B16_SSCALED,
1342         VK_FORMAT_R16G16B16_UINT,
1343         VK_FORMAT_R16G16B16_SINT,
1344         VK_FORMAT_R16G16B16_SFLOAT,
1345         VK_FORMAT_R16G16B16A16_UNORM,
1346         VK_FORMAT_R16G16B16A16_SNORM,
1347         VK_FORMAT_R16G16B16A16_USCALED,
1348         VK_FORMAT_R16G16B16A16_SSCALED,
1349         VK_FORMAT_R16G16B16A16_UINT,
1350         VK_FORMAT_R16G16B16A16_SINT,
1351         VK_FORMAT_R16G16B16A16_SFLOAT,
1352         VK_FORMAT_R32_UINT,
1353         VK_FORMAT_R32_SINT,
1354         VK_FORMAT_R32_SFLOAT,
1355         VK_FORMAT_R32G32_UINT,
1356         VK_FORMAT_R32G32_SINT,
1357         VK_FORMAT_R32G32_SFLOAT,
1358         VK_FORMAT_R32G32B32_UINT,
1359         VK_FORMAT_R32G32B32_SINT,
1360         VK_FORMAT_R32G32B32_SFLOAT,
1361         VK_FORMAT_R32G32B32A32_UINT,
1362         VK_FORMAT_R32G32B32A32_SINT,
1363         VK_FORMAT_R32G32B32A32_SFLOAT,
1364         VK_FORMAT_R64_UINT,
1365         VK_FORMAT_R64_SINT,
1366         VK_FORMAT_R64_SFLOAT,
1367         VK_FORMAT_R64G64_UINT,
1368         VK_FORMAT_R64G64_SINT,
1369         VK_FORMAT_R64G64_SFLOAT,
1370         VK_FORMAT_R64G64B64_UINT,
1371         VK_FORMAT_R64G64B64_SINT,
1372         VK_FORMAT_R64G64B64_SFLOAT,
1373         VK_FORMAT_R64G64B64A64_UINT,
1374         VK_FORMAT_R64G64B64A64_SINT,
1375         VK_FORMAT_R64G64B64A64_SFLOAT,
1376         VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1377         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1378         VK_FORMAT_D16_UNORM,
1379         VK_FORMAT_X8_D24_UNORM_PACK32,
1380         VK_FORMAT_D32_SFLOAT,
1381         VK_FORMAT_S8_UINT,
1382         VK_FORMAT_D16_UNORM_S8_UINT,
1383         VK_FORMAT_D24_UNORM_S8_UINT,
1384         VK_FORMAT_D32_SFLOAT_S8_UINT,
1385         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
1386         VK_FORMAT_BC1_RGB_SRGB_BLOCK,
1387         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
1388         VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1389         VK_FORMAT_BC2_UNORM_BLOCK,
1390         VK_FORMAT_BC2_SRGB_BLOCK,
1391         VK_FORMAT_BC3_UNORM_BLOCK,
1392         VK_FORMAT_BC3_SRGB_BLOCK,
1393         VK_FORMAT_BC4_UNORM_BLOCK,
1394         VK_FORMAT_BC4_SNORM_BLOCK,
1395         VK_FORMAT_BC5_UNORM_BLOCK,
1396         VK_FORMAT_BC5_SNORM_BLOCK,
1397         VK_FORMAT_BC6H_UFLOAT_BLOCK,
1398         VK_FORMAT_BC6H_SFLOAT_BLOCK,
1399         VK_FORMAT_BC7_UNORM_BLOCK,
1400         VK_FORMAT_BC7_SRGB_BLOCK,
1401         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1402         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1403         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1404         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1405         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1406         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1407         VK_FORMAT_EAC_R11_UNORM_BLOCK,
1408         VK_FORMAT_EAC_R11_SNORM_BLOCK,
1409         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1410         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1411         VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1412         VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
1413         VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
1414         VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1415         VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
1416         VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
1417         VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1418         VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
1419         VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
1420         VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1421         VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
1422         VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
1423         VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1424         VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
1425         VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
1426         VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1427         VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
1428         VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
1429         VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1430         VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
1431         VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
1432         VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1433         VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
1434         VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
1435         VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1436         VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
1437         VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
1438         VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1439         VK_FORMAT_G8B8G8R8_422_UNORM,
1440         VK_FORMAT_B8G8R8G8_422_UNORM,
1441         VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
1442         VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1443         VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
1444         VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
1445         VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
1446         VK_FORMAT_R10X6_UNORM_PACK16,
1447         VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
1448         VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
1449         VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
1450         VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
1451         VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
1452         VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
1453         VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
1454         VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
1455         VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
1456         VK_FORMAT_R12X4_UNORM_PACK16,
1457         VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
1458         VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
1459         VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
1460         VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
1461         VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
1462         VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
1463         VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
1464         VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
1465         VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
1466         VK_FORMAT_G16B16G16R16_422_UNORM,
1467         VK_FORMAT_B16G16R16G16_422_UNORM,
1468         VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
1469         VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
1470         VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
1471         VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
1472         VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
1473         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
1474         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
1475         VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,
1476         VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT,
1477         VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT,
1478         VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT,
1479     };
1480     const DeviceInterface &vk         = context.getDeviceInterface();
1481     const InstanceInterface &vki      = context.getInstanceInterface();
1482     const VkDevice device             = context.getDevice();
1483     const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1484     const VkImageCreateFlags sparseFlags =
1485         VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1486     const VkImageUsageFlags transientFlags = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1487 
1488     const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physDevice);
1489     const uint32_t notInitializedBits                       = ~0u;
1490     const VkImageAspectFlags colorAspect                    = VK_IMAGE_ASPECT_COLOR_BIT;
1491     const VkImageAspectFlags depthStencilAspect             = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1492     const VkImageAspectFlags allAspects[2]                  = {colorAspect, depthStencilAspect};
1493     tcu::TestLog &log                                       = context.getTestContext().getLog();
1494     bool allPass                                            = true;
1495     uint32_t numCheckedImages                               = 0u;
1496 
1497     log << tcu::TestLog::Message
1498         << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
1499 
1500     for (uint32_t loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
1501     {
1502         const VkImageAspectFlags aspect = allAspects[loopAspectNdx];
1503         uint32_t previousMemoryTypeBits = notInitializedBits;
1504 
1505         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1506         {
1507             const VkFormat format = formats[formatNdx];
1508 
1509             if (isFormatMatchingAspect(format, aspect))
1510             {
1511                 // memoryTypeBits may differ between depth/stencil formats
1512                 if (aspect == depthStencilAspect)
1513                     previousMemoryTypeBits = notInitializedBits;
1514 
1515                 for (VkImageType loopImageType = VK_IMAGE_TYPE_1D; loopImageType != VK_IMAGE_TYPE_LAST;
1516                      loopImageType             = nextEnum(loopImageType))
1517                     for (VkImageCreateFlags loopCreateFlags = (VkImageCreateFlags)0;
1518                          loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
1519                          loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags))
1520                         for (VkImageUsageFlags loopUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1521                              loopUsageFlags <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1522                              loopUsageFlags = nextFlagExcluding(loopUsageFlags, transientFlags))
1523                             for (VkSampleCountFlagBits loopSampleCount                      = VK_SAMPLE_COUNT_1_BIT;
1524                                  loopSampleCount <= VK_SAMPLE_COUNT_16_BIT; loopSampleCount = nextFlag(loopSampleCount))
1525                             {
1526                                 const VkImageCreateFlags actualCreateFlags = loopCreateFlags | params.flags;
1527                                 const VkImageUsageFlags actualUsageFlags =
1528                                     loopUsageFlags | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT :
1529                                                                                      (VkImageUsageFlagBits)0);
1530                                 const bool isCube = (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
1531                                 const VkImageCreateInfo imageInfo = {
1532                                     VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType          sType;
1533                                     DE_NULL,                             // const void*              pNext;
1534                                     actualCreateFlags,                   // VkImageCreateFlags       flags;
1535                                     loopImageType, // VkImageType              imageType;
1536                                     format,        // VkFormat                 format;
1537                                     makeExtentForImage(loopImageType), // VkExtent3D               extent;
1538                                     1u,                        // uint32_t                 mipLevels;
1539                                     (isCube ? 6u : 1u),        // uint32_t                 arrayLayers;
1540                                     loopSampleCount,           // VkSampleCountFlagBits    samples;
1541                                     params.tiling,             // VkImageTiling            tiling;
1542                                     actualUsageFlags,          // VkImageUsageFlags        usage;
1543                                     VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode;
1544                                     0u,      // uint32_t                 queueFamilyIndexCount;
1545                                     DE_NULL, // const uint32_t*          pQueueFamilyIndices;
1546                                     VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout            initialLayout;
1547                                 };
1548 
1549                                 m_currentTestImageInfo = imageInfo;
1550 
1551                                 if (!isImageSupported(context, vki, physDevice, m_currentTestImageInfo))
1552                                     continue;
1553 
1554                                 log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo)
1555                                     << tcu::TestLog::EndMessage;
1556                                 ++numCheckedImages;
1557 
1558                                 tcu::ResultCollector result(log, "ERROR: ");
1559 
1560                                 updateMemoryRequirements(vk, device);
1561 
1562                                 verifyMemoryRequirements(result, memoryProperties);
1563 
1564                                 // For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1565                                 result.check((previousMemoryTypeBits == notInitializedBits) ||
1566                                                              (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1567                                                          "memoryTypeBits differ from the ones in the previous image configuration");
1568 
1569                                 if (result.getResult() != QP_TEST_RESULT_PASS)
1570                                     allPass = false;
1571 
1572                                 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1573                             }
1574             }
1575         }
1576     }
1577 
1578     if (numCheckedImages == 0u)
1579         log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check"
1580             << tcu::TestLog::EndMessage;
1581 
1582     return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1583 }
1584 
1585 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1586 {
1587 public:
1588     static tcu::TestStatus testEntryPoint(Context &context, const ImageTestParams params);
1589 
1590 protected:
1591     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, const ImageTestParams arg0);
1592 
1593     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device);
1594 };
1595 
testEntryPoint(Context & context,const ImageTestParams params)1596 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint(Context &context, const ImageTestParams params)
1597 {
1598     ImageMemoryRequirementsExtended test;
1599 
1600     return test.execTest(context, params);
1601 }
1602 
checkSupportImageMemoryRequirementsExtended(Context & context,ImageTestParams params)1603 void checkSupportImageMemoryRequirementsExtended(Context &context, ImageTestParams params)
1604 {
1605     checkSupportImageMemoryRequirementsOriginal(context, params);
1606 
1607     context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
1608 }
1609 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)1610 void ImageMemoryRequirementsExtended::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
1611                                                           const ImageTestParams arg0)
1612 {
1613     addFunctionCase(group, name, checkSupportImageMemoryRequirementsExtended, testEntryPoint, arg0);
1614 }
1615 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)1616 void ImageMemoryRequirementsExtended::updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device)
1617 {
1618     m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1619 }
1620 
1621 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
1622 {
1623 public:
1624     static tcu::TestStatus testEntryPoint(Context &context, const ImageTestParams params);
1625 
1626 protected:
1627     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, const ImageTestParams arg0);
1628 
1629     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device);
1630 
1631     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
1632                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties);
1633 
1634 protected:
1635     VkBool32 m_currentTestPrefersDedicatedAllocation;
1636     VkBool32 m_currentTestRequiresDedicatedAllocation;
1637 };
1638 
testEntryPoint(Context & context,const ImageTestParams params)1639 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint(Context &context,
1640                                                                            const ImageTestParams params)
1641 {
1642     ImageMemoryRequirementsDedicatedAllocation test;
1643 
1644     return test.execTest(context, params);
1645 }
1646 
checkSupportImageMemoryRequirementsDedicatedAllocation(Context & context,ImageTestParams params)1647 void checkSupportImageMemoryRequirementsDedicatedAllocation(Context &context, ImageTestParams params)
1648 {
1649     checkSupportImageMemoryRequirementsExtended(context, params);
1650 
1651     context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
1652 }
1653 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)1654 void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
1655                                                                      const ImageTestParams arg0)
1656 {
1657     addFunctionCase(group, name, checkSupportImageMemoryRequirementsDedicatedAllocation, testEntryPoint, arg0);
1658 }
1659 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)1660 void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements(const DeviceInterface &vk,
1661                                                                           const VkDevice device)
1662 {
1663     const uint32_t invalidVkBool32 = static_cast<uint32_t>(~0);
1664 
1665     VkMemoryDedicatedRequirements dedicatedRequirements = {
1666         VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, // VkStructureType    sType
1667         DE_NULL,                                         // void*            pNext
1668         invalidVkBool32,                                 // VkBool32            prefersDedicatedAllocation
1669         invalidVkBool32                                  // VkBool32            requiresDedicatedAllocation
1670     };
1671 
1672     m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements);
1673     m_currentTestPrefersDedicatedAllocation  = dedicatedRequirements.prefersDedicatedAllocation;
1674     m_currentTestRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation;
1675 }
1676 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties)1677 void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements(
1678     tcu::ResultCollector &result, const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties)
1679 {
1680     ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties);
1681 
1682     result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
1683                  "Non-bool value in m_currentTestPrefersDedicatedAllocation");
1684 
1685     result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
1686                  "Test design expects m_currentTestRequiresDedicatedAllocation to be false");
1687 }
1688 
1689 #ifndef CTS_USES_VULKANSC
1690 class ImageMemoryRequirementsCreateInfo : public ImageMemoryRequirementsExtended
1691 {
1692 public:
1693     static tcu::TestStatus testEntryPoint(Context &context, const ImageTestParams params);
1694 
1695 protected:
1696     virtual void addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name, const ImageTestParams arg0);
1697 
1698     virtual void updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device);
1699 
1700     virtual void verifyMemoryRequirements(tcu::ResultCollector &result,
1701                                           const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties);
1702 
1703     VkMemoryRequirements m_currentTestOriginalRequirements;
1704     VkMemoryRequirements m_currentTestHalfRequirements;
1705     std::vector<VkSparseImageMemoryRequirements> m_currentTestOriginalSparseRequirements;
1706 };
1707 
testEntryPoint(Context & context,const ImageTestParams params)1708 tcu::TestStatus ImageMemoryRequirementsCreateInfo::testEntryPoint(Context &context, const ImageTestParams params)
1709 {
1710     ImageMemoryRequirementsCreateInfo test;
1711 
1712     return test.execTest(context, params);
1713 }
1714 
checkSupportImageMemoryRequirementsCreateInfo(Context & context,ImageTestParams params)1715 void checkSupportImageMemoryRequirementsCreateInfo(Context &context, ImageTestParams params)
1716 {
1717     checkSupportImageMemoryRequirementsExtended(context, params);
1718 
1719     context.requireDeviceFunctionality("VK_KHR_maintenance4");
1720 }
1721 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)1722 void ImageMemoryRequirementsCreateInfo::addFunctionTestCase(tcu::TestCaseGroup *group, const std::string &name,
1723                                                             const ImageTestParams arg0)
1724 {
1725     addFunctionCase(group, name, checkSupportImageMemoryRequirementsCreateInfo, testEntryPoint, arg0);
1726 }
1727 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)1728 void ImageMemoryRequirementsCreateInfo::updateMemoryRequirements(const DeviceInterface &vk, const VkDevice device)
1729 {
1730     m_currentTestRequirements = getDeviceImageMemoryRequirements(vk, device, m_currentTestImageInfo);
1731 
1732     const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
1733     m_currentTestOriginalRequirements = getImageMemoryRequirements(vk, device, *image);
1734 
1735     VkImageCreateInfo halfImageCreateInfo = m_currentTestImageInfo;
1736     halfImageCreateInfo.extent    = halfExtentForImage(m_currentTestImageInfo.imageType, m_currentTestImageInfo.extent);
1737     m_currentTestHalfRequirements = getDeviceImageMemoryRequirements(vk, device, halfImageCreateInfo);
1738 
1739     if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1740     {
1741         m_currentTestSparseRequirements =
1742             getImageCreateInfoSparseMemoryRequirements(vk, device, m_currentTestImageInfo);
1743         m_currentTestOriginalSparseRequirements = getImageSparseMemoryRequirements(vk, device, *image);
1744     }
1745 }
1746 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties)1747 void ImageMemoryRequirementsCreateInfo::verifyMemoryRequirements(
1748     tcu::ResultCollector &result, const VkPhysicalDeviceMemoryProperties &deviceMemoryProperties)
1749 {
1750     ImageMemoryRequirementsOriginal::verifyMemoryRequirements(result, deviceMemoryProperties);
1751 
1752     result.check(m_currentTestRequirements.alignment == m_currentTestOriginalRequirements.alignment,
1753                  "VkMemoryRequirements alignment queried from vkImageCreateInfo differs from equivalent object query");
1754 
1755     result.check(
1756         m_currentTestRequirements.memoryTypeBits == m_currentTestOriginalRequirements.memoryTypeBits,
1757         "VkMemoryRequirements memoryTypeBits queried from vkImageCreateInfo differs from equivalent object query");
1758 
1759     result.check(m_currentTestRequirements.size == m_currentTestOriginalRequirements.size,
1760                  "VkMemoryRequirements size queried from vkImageCreateInfo differs from equivalent object query");
1761 
1762     result.check(m_currentTestRequirements.size >= m_currentTestHalfRequirements.size,
1763                  "VkMemoryRequirements size queried from vkImageCreateInfo is larger for a smaller image");
1764 
1765     if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1766     {
1767         result.check(m_currentTestSparseRequirements.size() == m_currentTestOriginalSparseRequirements.size(),
1768                      "VkSparseImageMemoryRequirements count queried from vkImageCreateInfo differs from equivalent "
1769                      "object query");
1770 
1771         for (uint32_t ndx = 0; ndx < m_currentTestSparseRequirements.size(); ++ndx)
1772         {
1773             const VkSparseImageMemoryRequirements &sparseRequirementsFromCreateInfo =
1774                 m_currentTestSparseRequirements[ndx];
1775             const VkSparseImageMemoryRequirements &sparseRequirementsFromObject =
1776                 m_currentTestOriginalSparseRequirements[ndx];
1777 
1778             result.check(sparseRequirementsFromCreateInfo.formatProperties.aspectMask ==
1779                              sparseRequirementsFromObject.formatProperties.aspectMask,
1780                          "VkSparseImageMemoryRequirements aspectMask queried from vkImageCreateInfo differs from "
1781                          "equivalent object query");
1782 
1783             result.check(sparseRequirementsFromCreateInfo.formatProperties.flags ==
1784                              sparseRequirementsFromObject.formatProperties.flags,
1785                          "VkSparseImageMemoryRequirements flags queried from vkImageCreateInfo differs from equivalent "
1786                          "object query");
1787 
1788             result.check(sparseRequirementsFromCreateInfo.formatProperties.imageGranularity.width ==
1789                              sparseRequirementsFromObject.formatProperties.imageGranularity.width,
1790                          "VkSparseImageMemoryRequirements imageGranularity queried from vkImageCreateInfo differs from "
1791                          "equivalent object query");
1792             result.check(sparseRequirementsFromCreateInfo.formatProperties.imageGranularity.height ==
1793                              sparseRequirementsFromObject.formatProperties.imageGranularity.height,
1794                          "VkSparseImageMemoryRequirements imageGranularity queried from vkImageCreateInfo differs from "
1795                          "equivalent object query");
1796             result.check(sparseRequirementsFromCreateInfo.formatProperties.imageGranularity.depth ==
1797                              sparseRequirementsFromObject.formatProperties.imageGranularity.depth,
1798                          "VkSparseImageMemoryRequirements imageGranularity queried from vkImageCreateInfo differs from "
1799                          "equivalent object query");
1800 
1801             result.check(sparseRequirementsFromCreateInfo.imageMipTailFirstLod ==
1802                              sparseRequirementsFromObject.imageMipTailFirstLod,
1803                          "VkSparseImageMemoryRequirements imageMipTailFirstLod queried from vkImageCreateInfo differs "
1804                          "from equivalent object query");
1805 
1806             result.check(sparseRequirementsFromCreateInfo.imageMipTailSize ==
1807                              sparseRequirementsFromObject.imageMipTailSize,
1808                          "VkSparseImageMemoryRequirements imageMipTailSize queried from vkImageCreateInfo differs from "
1809                          "equivalent object query");
1810 
1811             result.check(sparseRequirementsFromCreateInfo.imageMipTailOffset ==
1812                              sparseRequirementsFromObject.imageMipTailOffset,
1813                          "VkSparseImageMemoryRequirements imageMipTailOffset queried from vkImageCreateInfo differs "
1814                          "from equivalent object query");
1815 
1816             result.check(sparseRequirementsFromCreateInfo.imageMipTailStride ==
1817                              sparseRequirementsFromObject.imageMipTailStride,
1818                          "VkSparseImageMemoryRequirements imageMipTailStride queried from vkImageCreateInfo differs "
1819                          "from equivalent object query");
1820         }
1821     }
1822 }
1823 #endif // CTS_USES_VULKANSC
1824 
populateCoreTestGroup(tcu::TestCaseGroup * group)1825 void populateCoreTestGroup(tcu::TestCaseGroup *group)
1826 {
1827     BufferMemoryRequirementsOriginal bufferTest;
1828     ImageMemoryRequirementsOriginal imageTest;
1829 
1830     bufferTest.populateTestGroup(group);
1831     imageTest.populateTestGroup(group);
1832 }
1833 
populateExtendedTestGroup(tcu::TestCaseGroup * group)1834 void populateExtendedTestGroup(tcu::TestCaseGroup *group)
1835 {
1836     BufferMemoryRequirementsExtended bufferTest;
1837     ImageMemoryRequirementsExtended imageTest;
1838 
1839     bufferTest.populateTestGroup(group);
1840     imageTest.populateTestGroup(group);
1841 }
1842 
populateDedicatedAllocationTestGroup(tcu::TestCaseGroup * group)1843 void populateDedicatedAllocationTestGroup(tcu::TestCaseGroup *group)
1844 {
1845     BufferMemoryRequirementsDedicatedAllocation bufferTest;
1846     ImageMemoryRequirementsDedicatedAllocation imageTest;
1847 
1848     bufferTest.populateTestGroup(group);
1849     imageTest.populateTestGroup(group);
1850 }
1851 
isMultiplaneImageSupported(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & info)1852 bool isMultiplaneImageSupported(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice,
1853                                 const VkImageCreateInfo &info)
1854 {
1855     // cubemap requires arrayLayers > 1, which multiplane doesn't support
1856     if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
1857         return false;
1858 
1859     if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
1860         (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
1861                        VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
1862         return false;
1863 
1864     const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physicalDevice);
1865 
1866     if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
1867     {
1868         DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
1869 
1870         if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
1871             return false;
1872     }
1873 
1874     const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, info.format);
1875     const VkFormatFeatureFlags formatFeatures =
1876         (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures :
1877                                                  formatProperties.optimalTilingFeatures);
1878     if ((info.flags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0 && (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) == 0)
1879         return false;
1880 
1881     if (!doesUsageSatisfyFeatures(info.usage, formatFeatures))
1882         return false;
1883 
1884     VkImageFormatProperties imageFormatProperties;
1885     const VkResult result = vki.getPhysicalDeviceImageFormatProperties(
1886         physicalDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1887 
1888     if (VK_SUCCESS == result)
1889     {
1890         if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1891             return false;
1892         if (info.mipLevels > imageFormatProperties.maxMipLevels)
1893             return false;
1894         if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1895             return false;
1896     }
1897 
1898     return (VK_SUCCESS == result);
1899 }
1900 
testMultiplaneImages(Context & context,ImageTestParams params)1901 tcu::TestStatus testMultiplaneImages(Context &context, ImageTestParams params)
1902 {
1903     const VkFormat multiplaneFormats[] = {VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
1904                                           VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1905                                           VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
1906                                           VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
1907                                           VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
1908                                           VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
1909                                           VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
1910                                           VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
1911                                           VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
1912                                           VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
1913                                           VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
1914                                           VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
1915                                           VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
1916                                           VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
1917                                           VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
1918                                           VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
1919                                           VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
1920                                           VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
1921                                           VK_FORMAT_G16_B16R16_2PLANE_422_UNORM};
1922 
1923     std::vector<VkImageCreateFlags> nonSparseCreateFlags{
1924         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
1925         VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
1926         VK_IMAGE_CREATE_ALIAS_BIT
1927         /* VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT - present tests use only one physical device */
1928         ,
1929         VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT
1930         /* VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT not apply with planar formats */
1931         ,
1932         VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
1933         VK_IMAGE_CREATE_DISJOINT_BIT,
1934         VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT};
1935     if (context.getDeviceVulkan11Features().protectedMemory)
1936     {
1937         nonSparseCreateFlags.emplace_back(VK_IMAGE_CREATE_PROTECTED_BIT);
1938     }
1939 #ifndef CTS_USES_VULKANSC
1940     std::vector<VkImageCreateFlags> nonSparseCreateFlagsNoSC;
1941     if (context.isDeviceFunctionalitySupported(VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME))
1942     {
1943         nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV);
1944     }
1945     if (context.isDeviceFunctionalitySupported(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME))
1946     {
1947         nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT);
1948     }
1949     if (context.isDeviceFunctionalitySupported(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME))
1950     {
1951         nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT);
1952     }
1953     if (context.isDeviceFunctionalitySupported(VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME))
1954     {
1955         nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM);
1956     }
1957 
1958     auto isMultisampledRenderToSingleSampledEnabled = [&]() -> bool
1959     {
1960         bool enabled = false;
1961         if (context.isDeviceFunctionalitySupported(VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME))
1962         {
1963             const auto &feature = context.getMultisampledRenderToSingleSampledFeaturesEXT();
1964             enabled             = feature.multisampledRenderToSingleSampled != VK_FALSE;
1965         }
1966         return enabled;
1967     };
1968     if (isMultisampledRenderToSingleSampledEnabled())
1969         nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT);
1970     nonSparseCreateFlags.insert(nonSparseCreateFlags.end(), nonSparseCreateFlagsNoSC.begin(),
1971                                 nonSparseCreateFlagsNoSC.end());
1972 #endif // CTS_USES_VULKANSC
1973 
1974     const std::vector<VkImageCreateFlags> sparseCreateFlags{
1975         VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
1976         VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT};
1977 
1978     const bool isSparseTest((params.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0);
1979     const InstanceInterface &vki                            = context.getInstanceInterface();
1980     const VkPhysicalDevice physicalDevice                   = context.getPhysicalDevice();
1981     const DeviceInterface &vk                               = context.getDeviceInterface();
1982     const VkDevice device                                   = context.getDevice();
1983     const VkImageUsageFlags transientFlags                  = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1984     const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physicalDevice);
1985     tcu::TestLog &log                                       = context.getTestContext().getLog();
1986     tcu::ResultCollector result(log, "ERROR: ");
1987     std::set<VkFormat> supportedFormats{};
1988 
1989     log << TestLog::Message << "Memory properties: " << memoryProperties << TestLog::EndMessage;
1990 
1991     for (const VkFormat format : multiplaneFormats)
1992     {
1993         for (const VkImageCreateFlags loopCreateFlags : (isSparseTest ? sparseCreateFlags : nonSparseCreateFlags))
1994         {
1995             const VkImageType imageType =
1996                 ((loopCreateFlags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT)
1997 #ifndef CTS_USES_VULKANSC
1998                  || (loopCreateFlags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT)
1999 #endif // CTS_USES_VULKANSC
2000                      ) ?
2001                     isYCbCrConversionFormat(format) ? VK_IMAGE_TYPE_MAX_ENUM : VK_IMAGE_TYPE_3D :
2002                     VK_IMAGE_TYPE_2D;
2003             if (imageType == VK_IMAGE_TYPE_MAX_ENUM)
2004                 continue;
2005 
2006             if ((loopCreateFlags & VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT) &&
2007                 !isDepthStencilFormat(format))
2008                 continue;
2009 
2010             for (VkImageUsageFlags loopUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2011                  loopUsageFlags <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2012                  loopUsageFlags = nextFlagExcluding(loopUsageFlags, transientFlags))
2013             {
2014                 const VkImageCreateFlags actualCreateFlags = loopCreateFlags | (isSparseTest ? params.flags : 0);
2015                 const VkImageUsageFlags actualUsageFlags =
2016                     loopUsageFlags |
2017                     (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
2018                 const uint32_t arrayLayers =
2019                     ((imageType == VK_IMAGE_TYPE_2D) && (loopCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) ? 6u :
2020                                                                                                                    1u;
2021                 const VkImageCreateInfo imageInfo = {
2022                     VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType          sType;
2023                     DE_NULL,                             // const void*              pNext;
2024                     actualCreateFlags,                   // VkImageCreateFlags       flags;
2025                     imageType,                           // VkImageType              imageType;
2026                     format,                              // VkFormat                 format;
2027                     {
2028                         64u,
2029                         64u,
2030                         1u,
2031                     },                         // VkExtent3D               extent;
2032                     1u,                        // uint32_t                 mipLevels;
2033                     arrayLayers,               // uint32_t                 arrayLayers;
2034                     VK_SAMPLE_COUNT_1_BIT,     // VkSampleCountFlagBits    samples;
2035                     params.tiling,             // VkImageTiling            tiling;
2036                     actualUsageFlags,          // VkImageUsageFlags        usage;
2037                     VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode            sharingMode;
2038                     0u,                        // uint32_t                 queueFamilyIndexCount;
2039                     DE_NULL,                   // const uint32_t*          pQueueFamilyIndices;
2040                     VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout            initialLayout;
2041                 };
2042 
2043                 if (isMultiplaneImageSupported(vki, physicalDevice, imageInfo))
2044                 {
2045                     const Unique<VkImage> image((params.useMaint4) ? Move<VkImage>() :
2046                                                                      createImage(vk, device, &imageInfo));
2047 
2048                     log << tcu::TestLog::Message << "- " << getImageInfoString(imageInfo) << tcu::TestLog::EndMessage;
2049 
2050                     supportedFormats.insert(format);
2051 
2052                     for (uint32_t planeNdx = 0; planeNdx < (uint32_t)getPlaneCount(format); planeNdx++)
2053                     {
2054                         VkMemoryRequirements2 requirements = {
2055                             VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, DE_NULL, {0u, 0u, 0u}};
2056                         const VkImageAspectFlagBits aspect = getPlaneAspect(planeNdx);
2057 
2058 #ifndef CTS_USES_VULKANSC
2059                         if (params.useMaint4)
2060                         {
2061                             const VkDeviceImageMemoryRequirementsKHR info = {
2062                                 VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR, DE_NULL, &imageInfo, aspect};
2063                             vk.getDeviceImageMemoryRequirements(device, &info, &requirements);
2064                         }
2065                         else
2066                         {
2067 #endif // CTS_USES_VULKANSC
2068                             const VkImagePlaneMemoryRequirementsInfo aspectInfo = {
2069                                 VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, DE_NULL, aspect};
2070                             const VkImageMemoryRequirementsInfo2 info = {
2071                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2072                                 (actualCreateFlags & VK_IMAGE_CREATE_DISJOINT_BIT) == 0 ? DE_NULL : &aspectInfo,
2073                                 *image};
2074 
2075                             vk.getImageMemoryRequirements2(device, &info, &requirements);
2076 #ifndef CTS_USES_VULKANSC
2077                         }
2078 #endif // CTS_USES_VULKANSC
2079 
2080                         log << TestLog::Message << "Aspect: " << getImageAspectFlagsStr(aspect)
2081                             << ", Requirements: " << requirements << TestLog::EndMessage;
2082 
2083                         result.check(deIsPowerOfTwo64(static_cast<uint64_t>(requirements.memoryRequirements.alignment)),
2084                                      "VkMemoryRequirements alignment isn't power of two");
2085 
2086 #ifndef CTS_USES_VULKANSC
2087                         if (actualCreateFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
2088                         {
2089                             std::vector<VkSparseImageMemoryRequirements> sparseRequirements;
2090                             if ((*image == DE_NULL) || params.useMaint4)
2091                                 sparseRequirements =
2092                                     getDeviceImageSparseMemoryRequirements(vk, device, imageInfo, aspect);
2093                             else
2094                                 sparseRequirements = getImageSparseMemoryRequirements(vk, device, *image);
2095 
2096                             for (const VkSparseImageMemoryRequirements &sr : sparseRequirements)
2097                             {
2098                                 if (sr.formatProperties.aspectMask == aspect)
2099                                 {
2100                                     result.check((sr.imageMipTailSize % requirements.memoryRequirements.alignment) == 0,
2101                                                  "VkSparseImageMemoryRequirements::imageMipTailSize is not aligned "
2102                                                  "with sparse block size");
2103                                     break;
2104                                 }
2105                             }
2106                         }
2107 #endif // CTS_USES_VULKANSC
2108 
2109                         if (result.check(requirements.memoryRequirements.memoryTypeBits != 0,
2110                                          "No supported memory types"))
2111                         {
2112                             typedef std::vector<uint32_t>::const_iterator IndexIterator;
2113                             const std::vector<uint32_t> usedMemoryTypeIndices =
2114                                 bitsToIndices(requirements.memoryRequirements.memoryTypeBits);
2115                             bool hasHostVisibleType = false;
2116 
2117                             for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin();
2118                                  memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
2119                             {
2120                                 if (result.check(*memoryTypeNdx < memoryProperties.memoryTypeCount,
2121                                                  "Unknown memory type bits set in memory requirements"))
2122                                 {
2123                                     const VkMemoryPropertyFlags propertyFlags(
2124                                         memoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags);
2125 
2126                                     if (propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
2127                                         hasHostVisibleType = true;
2128 
2129                                     if (propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
2130                                     {
2131                                         result.check((imageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
2132                                                      "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for "
2133                                                      "a non-transient attachment image");
2134                                     }
2135                                 }
2136                                 else
2137                                     break;
2138                             }
2139 
2140                             result.check(params.tiling != VK_IMAGE_TILING_LINEAR ||
2141                                              (hasHostVisibleType || (loopCreateFlags & VK_IMAGE_CREATE_PROTECTED_BIT)),
2142                                          "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2143                         }
2144                     }
2145                 }
2146             }
2147         }
2148     }
2149 
2150     if (supportedFormats.size() == 0)
2151     {
2152         return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED,
2153                                "None of tested in given configuration multiplanar formats is supported by device.");
2154     }
2155 
2156     return tcu::TestStatus(result.getResult(), result.getMessage());
2157 }
2158 
checkSupportMultiplane(Context & context,ImageTestParams params)2159 void checkSupportMultiplane(Context &context, ImageTestParams params)
2160 {
2161     checkSupportImageMemoryRequirementsOriginal(context, params);
2162 
2163     context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
2164     context.requireDeviceFunctionality("VK_KHR_sampler_ycbcr_conversion");
2165 
2166     if (params.useMaint4)
2167         context.requireDeviceFunctionality("VK_KHR_maintenance4");
2168 }
2169 
populateMultiplaneTestGroup(tcu::TestCaseGroup * group,bool useMaint4)2170 void populateMultiplaneTestGroup(tcu::TestCaseGroup *group, bool useMaint4)
2171 {
2172     const struct
2173     {
2174         VkImageCreateFlags flags;
2175         bool transient;
2176         const char *const name;
2177     } imageFlagsCases[] = {
2178         {(VkImageCreateFlags)0, false, "regular"},
2179         {(VkImageCreateFlags)0, true, "transient"},
2180         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT, false, "sparse"},
2181         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, false, "sparse_residency"},
2182         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_aliased"},
2183         {VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
2184          false, "sparse_residency_aliased"},
2185     };
2186     const struct
2187     {
2188         VkImageTiling value;
2189         const char *name;
2190     } tilings[] = {{VK_IMAGE_TILING_OPTIMAL, "optimal"}, {VK_IMAGE_TILING_LINEAR, "linear"}};
2191 
2192     for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
2193         for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); ++tilingNdx)
2194         {
2195             const VkImageCreateFlags flags = imageFlagsCases[flagsNdx].flags;
2196             const bool transient           = imageFlagsCases[flagsNdx].transient;
2197             const VkImageTiling tiling     = tilings[tilingNdx].value;
2198             const ImageTestParams params(flags, tiling, transient, useMaint4);
2199             const std::string name = std::string(imageFlagsCases[flagsNdx].name) + "_" + tilings[tilingNdx].name;
2200 
2201             if (tiling == VK_IMAGE_TILING_LINEAR && (flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0)
2202                 continue;
2203 
2204             addFunctionCase(group, name, checkSupportMultiplane, testMultiplaneImages, params);
2205         }
2206 }
2207 
testVkMemoryPropertyFlags(Context & context)2208 tcu::TestStatus testVkMemoryPropertyFlags(Context &context)
2209 {
2210     VkMemoryPropertyFlags propertyFlagSets[] = {
2211         0,
2212         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2213         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2214         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2215         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2216         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
2217             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2218         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2219         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
2220             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2221         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT,
2222         VK_MEMORY_PROPERTY_PROTECTED_BIT,
2223         VK_MEMORY_PROPERTY_PROTECTED_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2224 #ifndef CTS_USES_VULKANSC
2225         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
2226             VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2227         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
2228             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2229         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2230         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
2231             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2232         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
2233             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2234         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
2235             VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2236         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
2237             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
2238             VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2239         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
2240             VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2241         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
2242             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
2243             VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2244         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
2245             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
2246             VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2247         VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV
2248 #endif // CTS_USES_VULKANSC
2249     };
2250 
2251     const InstanceInterface &vki          = context.getInstanceInterface();
2252     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
2253     VkPhysicalDeviceMemoryProperties memoryProperties;
2254     uint32_t matchingTypes = 0;
2255     tcu::TestLog &log      = context.getTestContext().getLog();
2256     tcu::ResultCollector result(log, "ERROR: ");
2257 
2258     vki.getPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
2259 
2260     for (uint32_t ndx = 0; ndx < memoryProperties.memoryTypeCount; ndx++)
2261     {
2262         for (auto &flag : propertyFlagSets)
2263         {
2264             if (memoryProperties.memoryTypes[ndx].propertyFlags == flag)
2265                 matchingTypes++;
2266         }
2267     }
2268 
2269     std::string diffStr = std::to_string(int(memoryProperties.memoryTypeCount - matchingTypes));
2270 
2271     result.check(matchingTypes == memoryProperties.memoryTypeCount,
2272                  "Unknown memory type bits set in memory requirements: " + diffStr + " mismatch");
2273 
2274     return tcu::TestStatus(result.getResult(), result.getMessage());
2275 }
2276 
populateMemoryPropertyFlagsTestGroup(tcu::TestCaseGroup * group)2277 void populateMemoryPropertyFlagsTestGroup(tcu::TestCaseGroup *group)
2278 {
2279     addFunctionCase(group, "check_all", testVkMemoryPropertyFlags);
2280 }
2281 
populateMultiplaneTestGroup(tcu::TestCaseGroup * group)2282 void populateMultiplaneTestGroup(tcu::TestCaseGroup *group)
2283 {
2284     populateMultiplaneTestGroup(group, false);
2285 }
2286 
2287 #ifndef CTS_USES_VULKANSC
populateCreateInfoTestGroup(tcu::TestCaseGroup * group)2288 void populateCreateInfoTestGroup(tcu::TestCaseGroup *group)
2289 {
2290     BufferMemoryRequirementsCreateInfo bufferTest;
2291     ImageMemoryRequirementsCreateInfo imageTest;
2292 
2293     bufferTest.populateTestGroup(group);
2294     imageTest.populateTestGroup(group);
2295 
2296     de::MovePtr<tcu::TestCaseGroup> multiplaneGroup(
2297         new tcu::TestCaseGroup(group->getTestContext(), "multiplane_image"));
2298     populateMultiplaneTestGroup(multiplaneGroup.get(), true);
2299     group->addChild(multiplaneGroup.release());
2300 }
2301 #endif // CTS_USES_VULKANSC
2302 
2303 } // namespace
2304 
createRequirementsTests(tcu::TestContext & testCtx)2305 tcu::TestCaseGroup *createRequirementsTests(tcu::TestContext &testCtx)
2306 {
2307     // Buffer and image memory requirements
2308     de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements"));
2309 
2310     // Memory requirements tests with core functionality
2311     requirementsGroup->addChild(createTestGroup(testCtx, "core", populateCoreTestGroup));
2312     // Memory requirements tests with extension VK_KHR_get_memory_requirements2
2313     requirementsGroup->addChild(createTestGroup(testCtx, "extended", populateExtendedTestGroup));
2314     // Memory requirements tests with extension VK_KHR_dedicated_allocation
2315     requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation", populateDedicatedAllocationTestGroup));
2316     // Memory requirements tests with vkGetImagePlaneMemoryRequirements
2317     requirementsGroup->addChild(createTestGroup(testCtx, "multiplane_image", populateMultiplaneTestGroup));
2318     // Memory requirements tests with vkGetPhysicalDeviceMemoryProperties
2319     requirementsGroup->addChild(
2320         createTestGroup(testCtx, "memory_property_flags", populateMemoryPropertyFlagsTestGroup));
2321 #ifndef CTS_USES_VULKANSC
2322     // Memory requirements tests with extension VK_KHR_maintenance4
2323     requirementsGroup->addChild(createTestGroup(testCtx, "create_info", populateCreateInfoTestGroup));
2324 #endif // CTS_USES_VULKANSC
2325 
2326     return requirementsGroup.release();
2327 }
2328 
2329 } // namespace memory
2330 } // namespace vkt
2331