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