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