1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 The Khronos Group Inc.
6 * Copyright (c) 2016 The Android Open Source Project
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Cover for non-zero of memoryTypeBits from vkGetBufferMemoryRequirements*() tests.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktApiBufferMemoryRequirementsTests.hpp"
26 #include "vktApiBufferMemoryRequirementsTestsUtils.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28
29 #include "vkMemUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "deFilePath.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuCommandLine.hpp"
37
38 #include <algorithm>
39 #include <array>
40 #include <functional>
41 #include <iostream>
42 #include <set>
43 #include <sstream>
44 #include <tuple>
45 #include <vector>
46
47 namespace vkt
48 {
49 namespace api
50 {
51 namespace
52 {
53
54 using namespace de;
55 using namespace vk;
56 using namespace tcu;
57
58 struct TestConfig;
59 struct InstanceConfig;
60
61 enum BufferFateFlagBits
62 {
63 Transfer = 0x01,
64 Storage = 0x02,
65 Other = 0x04,
66 AccStructure = 0x08,
67 Video = 0x10
68 };
69 typedef deUint32 BufferFateFlags;
70 typedef typename std::add_pointer<typename std::add_const<char>::type>::type cstr;
71 typedef u::BitsSet<BufferFateFlags, BufferFateFlagBits, cstr> BufferFateBits;
72
73 const BufferFateBits AvailableBufferFateBits
74 {
75 std::make_tuple(Transfer, "transfer_usage_bits" ),
76 std::make_tuple(Storage, "storage_usage_bits" ),
77 std::make_tuple(Other, "other_usage_bits" ),
78 std::make_tuple(AccStructure, "acc_struct_usage_bits" ),
79 std::make_tuple(Video, "video_usage_bits" ),
80 };
81
82 typedef u::BitsSet<VkBufferCreateFlags, VkBufferCreateFlagBits, cstr> BufferCreateBits;
83 typedef u::BitsSet<VkBufferUsageFlags, VkBufferUsageFlagBits, BufferFateFlagBits> BufferUsageBits;
84 typedef u::BitsSet<VkExternalMemoryHandleTypeFlags,
85 VkExternalMemoryHandleTypeFlagBits, cstr, bool> ExternalMemoryHandleBits;
86 typedef SharedPtr<BufferCreateBits> BufferCreateBitsPtr;
87 typedef SharedPtr<BufferUsageBits> BufferUsageBitsPtr;
88 typedef SharedPtr<ExternalMemoryHandleBits> ExternalMemoryHandleBitsPtr;
89
90 struct TestConfig
91 {
92 bool useMethod2;
93 SharedPtr<BufferCreateBits> createBits;
94 SharedPtr<BufferFateBits> fateBits;
95 bool incExtMemTypeFlags;
96 // Tests the buffer memory size requirement is less than or equal to the aligned size of the buffer.
97 // Requires VK_KHR_maintenance4 extension.
98 bool testSizeRequirements;
99 };
100 struct InstanceConfig
101 {
102 bool useMethod2;
103 SharedPtr<BufferCreateBits> createBits;
104 SharedPtr<BufferFateBits> fateBits;
105 SharedPtr<std::vector<BufferUsageBitsPtr>> usageFlags;
106 bool incExtMemTypeFlags;
107 SharedPtr<std::vector<ExternalMemoryHandleBitsPtr>> extMemHandleFlags;
108 bool testSizeRequirements;
109
InstanceConfigvkt::api::__anond1aac3cd0111::InstanceConfig110 InstanceConfig(const TestConfig& conf)
111 : useMethod2 (conf.useMethod2)
112 , createBits (conf.createBits)
113 , fateBits (conf.fateBits)
114 , usageFlags (new std::vector<SharedPtr<BufferUsageBits>>)
115 , incExtMemTypeFlags (conf.incExtMemTypeFlags)
116 , extMemHandleFlags (new std::vector<SharedPtr<ExternalMemoryHandleBits>>)
117 , testSizeRequirements (conf.testSizeRequirements) {}
118 };
119
120 const BufferCreateBits AvailableBufferCreateBits
121 {
122 std::make_tuple( VkBufferCreateFlagBits(0), "no_flags" ),
123 std::make_tuple( VK_BUFFER_CREATE_PROTECTED_BIT, "protected" ),
124 #ifndef CTS_USES_VULKANSC
125 std::make_tuple( VK_BUFFER_CREATE_SPARSE_BINDING_BIT, "sparse_binding" ),
126 std::make_tuple( VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, "sparse_residency" ),
127 std::make_tuple( VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, "sparse_aliased" ),
128 #endif // CTS_USES_VULKANSC
129 };
130
131 const BufferUsageBits AvailableBufferUsageBits
132 {
133 std::make_tuple( VK_BUFFER_USAGE_TRANSFER_SRC_BIT , Transfer ),
134 std::make_tuple( VK_BUFFER_USAGE_TRANSFER_DST_BIT , Transfer ),
135 std::make_tuple( VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT , Storage ),
136 std::make_tuple( VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT , Storage ),
137 std::make_tuple( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT , Storage ),
138 std::make_tuple( VK_BUFFER_USAGE_STORAGE_BUFFER_BIT , Storage ),
139 std::make_tuple( VK_BUFFER_USAGE_INDEX_BUFFER_BIT , Storage ),
140 std::make_tuple( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT , Storage ),
141 std::make_tuple( VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT , Other ),
142 std::make_tuple( VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT , Other ),
143 #ifndef CTS_USES_VULKANSC
144 std::make_tuple( VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR , Video ),
145 std::make_tuple( VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR , Video ),
146 std::make_tuple( VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT , Other ),
147 std::make_tuple( VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT , Other ),
148 std::make_tuple( VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT , Other ),
149 std::make_tuple( VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR , AccStructure ),
150 std::make_tuple( VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR , AccStructure ),
151 std::make_tuple( VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR , AccStructure ),
152 std::make_tuple( VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR , Video ),
153 std::make_tuple( VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR , Video ),
154 #endif // CTS_USES_VULKANSC
155 };
156
157 #define INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS VkExternalMemoryHandleTypeFlagBits(0)
158 const ExternalMemoryHandleBits AvailableExternalMemoryHandleBits
159 {
160 std::make_tuple( INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS , "no_flags", false ),
161 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT , "opaque_fd", false ),
162 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT , "opaque_win32", false ),
163 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT , "opaque_win32_kmt", false ),
164 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT , "d3d11_tex", false ),
165 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT , "d3d11_tex_kmt", false ),
166 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT , "d3d12_heap", false ),
167 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT , "d3d12_rsrc", false ),
168 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT , "dma_buf", false ),
169 #ifndef CTS_USES_VULKANSC
170 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID , "android_hw", false ),
171 #endif // CTS_USES_VULKANSC
172 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT , "host_alloc", true ),
173 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT , "host_mapped", true ),
174 #ifndef CTS_USES_VULKANSC
175 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA , "zircon_vmo", false ),
176 std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV , "roma_addr", false ),
177 #endif // CTS_USES_VULKANSC
178 };
179
180 template<class Flag, class Bit, class Str, class... Ignored>
bitsToString(const u::BitsSet<Flag,Bit,Str,Ignored...> & bits,const std::string & prefix=std::string ())181 std::string bitsToString (const u::BitsSet<Flag, Bit, Str, Ignored...>& bits,
182 const std::string& prefix = std::string())
183 {
184 DE_ASSERT(!bits.empty());
185 std::stringstream s;
186 s << prefix;
187 bool atLeastOne = false;
188 for (const auto& bit : bits) {
189 if (atLeastOne) s << '_';
190 s << std::get<1>(bit);
191 atLeastOne = true;
192 }
193 return s.str();
194 }
195
updateBufferCreateFlags(std::vector<BufferCreateBits> & flags)196 void updateBufferCreateFlags(std::vector<BufferCreateBits>& flags)
197 {
198 #ifndef CTS_USES_VULKANSC
199 const auto& residencyBit = AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT);
200 const auto& aliasedBit = AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT);
201 const auto& bindingBit = AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_BINDING_BIT);
202 const auto& protectedBit = AvailableBufferCreateBits.get(VK_BUFFER_CREATE_PROTECTED_BIT);
203 #endif // CTS_USES_VULKANSC
204 const auto& noneBit = AvailableBufferCreateBits.get(VkBufferCreateFlagBits(0));
205
206 #ifndef CTS_USES_VULKANSC
207 // VUID-VkBufferCreateInfo-flags-00918 { if sparse residency or sparse aliased include sparse binding }
208 for (auto& bits : flags)
209 {
210 if (bits.contains(residencyBit) || bits.contains(aliasedBit))
211 bits.insert(bindingBit);
212 }
213
214 // VUID-VkBufferCreateInfo-None-01888 { if sparse residency, sparse aliased or sparse binding then flags must not include protected }
215 const typename BufferCreateBits::key_type disallowdBits[] { residencyBit, aliasedBit, bindingBit };
216 for (auto i = flags.begin(); i != flags.end();)
217 {
218 auto& bits = *i;
219 if (bits.contains(protectedBit))
220 {
221 for (const auto& disallowdBit : disallowdBits)
222 {
223 auto find = bits.find(disallowdBit);
224 if (find != bits.end())
225 bits.erase(find);
226 }
227 }
228 i = bits.empty() ? flags.erase(i) : std::next(i);
229 }
230 #endif // CTS_USES_VULKANSC
231
232 // since 0 is a valid VkBufferCreateFlagBits flag then remove it flags where it exists along with other non-zero flags
233 for (auto i = flags.begin(); i != flags.end(); ++i)
234 {
235 auto& bits = *i;
236 auto find = bits.find(noneBit);
237 if (find != bits.end() && bits.size() > 1)
238 {
239 bits.erase(find);
240 }
241 }
242
243 // remove duplicates
244 for (auto i = flags.begin(); i != flags.end(); ++i)
245 {
246 for (auto j = std::next(i); j != flags.end();)
247 j = (*i == *j) ? flags.erase(j) : std::next(j);
248 }
249 }
250
251 class BufferMemoryRequirementsInstance : public TestInstance
252 {
253 public:
BufferMemoryRequirementsInstance(Context & context,const InstanceConfig config)254 BufferMemoryRequirementsInstance (Context& context,
255 const InstanceConfig config)
256 : TestInstance (context)
257 , m_config (config) {}
258
259 virtual ~BufferMemoryRequirementsInstance (void) override = default;
260 virtual tcu::TestStatus iterate (void) override;
261
262 void getBufferMemoryRequirements (VkMemoryRequirements& result,
263 const DeviceInterface& vkd,
264 VkDevice device,
265 VkBuffer buffer) const;
266 void getBufferMemoryRequirements2 (VkMemoryRequirements& result,
267 const DeviceInterface& vkd,
268 VkDevice device,
269 VkBuffer buffer) const;
270 typedef void (BufferMemoryRequirementsInstance::* Method) (VkMemoryRequirements& result,
271 const DeviceInterface& intf,
272 VkDevice device,
273 VkBuffer buffer) const;
274 template<class T, class... AddArgs>
275 void* chainVkStructure (void* pNext,
276 const AddArgs&... addArgs) const;
277 private:
278 void logFailedSubtests (const std::vector<BufferCreateBitsPtr>& failCreateBits,
279 const std::vector<BufferUsageBitsPtr>& failUsageBits,
280 const std::vector<ExternalMemoryHandleBitsPtr>& failExtMemHandleBits) const;
281 const InstanceConfig m_config;
282 };
283
284 class MemoryRequirementsTest : public TestCase
285 {
286 public:
MemoryRequirementsTest(TestContext & testCtx,const std::string & name,const TestConfig testConfig)287 MemoryRequirementsTest (TestContext& testCtx,
288 const std::string& name,
289 const TestConfig testConfig)
290 : TestCase (testCtx, name, std::string())
291 , m_testConfig (testConfig)
292 , m_instConfig (testConfig) {}
293
294 virtual ~MemoryRequirementsTest (void) override = default;
295 virtual void checkSupport (Context& context) const override;
createInstance(Context & context) const296 virtual TestInstance* createInstance (Context& context) const override
297 {
298 return new BufferMemoryRequirementsInstance(context, m_instConfig);
299 }
300
301 private:
302 const TestConfig m_testConfig;
303 InstanceConfig m_instConfig;
304 };
305
306 struct Info
307 {
308 enum Type {
309 Create,
310 Usage
311 } m_type;
312 std::ostringstream m_str;
313 cstr m_file;
314 int m_line;
Infovkt::api::__anond1aac3cd0111::Info315 template<class Msg> Info(Type type, const Msg& msg, cstr file, int line)
316 : m_type(type), m_str(), m_file(file), m_line(line) { m_str << msg; }
operator <<(std::ostringstream & str,const Info & info)317 friend std::ostringstream& operator<<(std::ostringstream& str, const Info& info) {
318 switch (info.m_type) {
319 case Create:
320 str << "Create buffer with " << info.m_str.str() << " not supported by device at "
321 << de::FilePath(info.m_file).getBaseName() << ":" << info.m_line;
322 break;
323 case Usage:
324 str << info.m_str.str() << " at "
325 << de::FilePath(info.m_file).getBaseName() << ":" << info.m_line;
326 break;
327 }
328 return str;
329 }
330 };
331 #define INFOCREATE(msg_) Info(Info::Create, (msg_), __FILE__, __LINE__)
332 #define INFOUSAGE(msg_) Info(Info::Usage, (msg_), __FILE__, __LINE__)
333
334 #ifndef CTS_USES_VULKANSC
readVideoCodecOperationFlagsKHR(const InstanceInterface & vki,const VkPhysicalDevice & device)335 VkVideoCodecOperationFlagsKHR readVideoCodecOperationFlagsKHR (const InstanceInterface& vki, const VkPhysicalDevice& device)
336 {
337 uint32_t queueFamilyPropertyCount = 0;
338 vki.getPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyPropertyCount, nullptr);
339 DE_ASSERT(queueFamilyPropertyCount);
340
341 std::vector<VkQueueFamilyVideoPropertiesKHR> videoQueueFamilyProperties(
342 queueFamilyPropertyCount,
343 {
344 VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR, // VkStructureType sType
345 nullptr, // void* pNext
346 0 // VkVideoCodecOperationFlagsKHR videoCodecOperations
347 });
348 std::vector<VkQueueFamilyProperties2> queueFamilyProperties(
349 queueFamilyPropertyCount,
350 {
351 VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2, // VkStructureType sType
352 nullptr, // void* pNext
353 {} // VkQueueFamilyProperties queueFamilyProperties
354 });
355 for (auto begin = queueFamilyProperties.begin(), i = begin, end = queueFamilyProperties.end(); i != end; ++i)
356 {
357 i->pNext = &videoQueueFamilyProperties.data()[std::distance(begin, i)];
358 }
359
360 vki.getPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyPropertyCount, queueFamilyProperties.data());
361
362 VkVideoCodecOperationFlagsKHR codecOperationFlags = VK_VIDEO_CODEC_OPERATION_NONE_KHR;
363 for (const VkQueueFamilyVideoPropertiesKHR& props : videoQueueFamilyProperties)
364 {
365 codecOperationFlags |= props.videoCodecOperations;
366 }
367
368 return codecOperationFlags;
369 }
370 #endif // CTS_USES_VULKANSC
371
checkSupport(Context & context) const372 void MemoryRequirementsTest::checkSupport (Context& context) const
373 {
374 const InstanceInterface& intf = context.getInstanceInterface();
375 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
376 auto& log = context.getTestContext().getLog();
377
378 if (m_testConfig.useMethod2)
379 context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
380
381 VkPhysicalDeviceProtectedMemoryFeatures protectedMemFeatures
382 {
383 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, // VkStructureType sType;
384 nullptr, // void* pNext;
385 VK_FALSE // VkBool32 protectedMemory;
386 };
387 VkPhysicalDeviceFeatures2 extFeatures
388 {
389 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // VkStructureType sType;
390 &protectedMemFeatures, // void* pNext;
391 {} // VkPhysicalDeviceFeatures features;
392 };
393 intf.getPhysicalDeviceFeatures2(physDevice, &extFeatures);
394
395 const VkPhysicalDeviceFeatures& features = extFeatures.features;
396 const VkBool32& protectedMemFeatureEnabled = protectedMemFeatures.protectedMemory;
397
398 // check the creating bits
399 {
400 std::ostringstream str;
401 bool notSupported = false;
402 const auto& createBits = *m_testConfig.createBits;
403
404 if (createBits.contains(VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && (VK_FALSE == features.sparseBinding))
405 {
406 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_BINDING_BIT));
407 notSupported = true;
408 }
409 if (createBits.contains(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && (VK_FALSE == features.sparseResidencyBuffer))
410 {
411 if (notSupported) str << std::endl;
412 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT));
413 notSupported = true;
414 }
415 if (createBits.contains(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && (VK_FALSE == features.sparseResidencyAliased))
416 {
417 if (notSupported) str << std::endl;
418 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT));
419 notSupported = true;
420 }
421 if (createBits.contains(VK_BUFFER_CREATE_PROTECTED_BIT) && (VK_FALSE == protectedMemFeatureEnabled))
422 {
423 if (notSupported) str << std::endl;
424 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_PROTECTED_BIT));
425 notSupported = true;
426 }
427 if (notSupported)
428 {
429 log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
430 TCU_THROW(NotSupportedError, "One or more create buffer flags not supported by device (check log for details)");
431 }
432 }
433
434 // check the usage bits and build instance input
435 {
436 std::vector<BufferUsageBits> usageFlags;
437 for (const auto& bit : *m_testConfig.fateBits)
438 {
439 auto fate = m_testConfig.fateBits->extract(bit);
440 std::vector<VkBufferUsageFlags> usageHints;
441 std::vector<BufferUsageBits> usageFlagsTmp;
442 u::combine(usageFlagsTmp, AvailableBufferUsageBits.select<1>(fate), usageHints);
443 u::mergeFlags(usageFlags, usageFlagsTmp);
444 }
445
446 std::ostringstream str;
447 std::array<bool, 7> msgs;
448 bool notSupported = false;
449 int entryCount = 0;
450 msgs.fill(false);
451
452 for (auto i = usageFlags.begin(); i != usageFlags.end();)
453 {
454 notSupported = false;
455
456 #ifndef CTS_USES_VULKANSC
457 if (i->any({VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
458 VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR})
459 && !context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
460 {
461 if (!msgs[0])
462 {
463 if (entryCount++) str << std::endl;
464 str << INFOUSAGE("VK_KHR_acceleration_structure not supported by device");
465 msgs[0] = true;
466 }
467 notSupported = true;
468 }
469 #endif // CTS_USES_VULKANSC
470
471 if (i->contains(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
472 && !context.isBufferDeviceAddressSupported())
473 {
474 if (!msgs[1])
475 {
476 if (entryCount++) str << std::endl;
477 str << INFOUSAGE("VK_EXT_buffer_device_address not supported by device");
478 msgs[1] = true;
479 }
480 notSupported = true;
481 }
482
483 #ifndef CTS_USES_VULKANSC
484 if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR,
485 VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
486 {
487 if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME))
488 {
489 if (!msgs[2])
490 {
491 if (entryCount++) str << std::endl;
492 str << INFOUSAGE("VK_EXT_video_queue not supported by device");
493 msgs[2] = true;
494 }
495 notSupported = true;
496 }
497 else
498 {
499 const VkVideoCodecOperationFlagsKHR videoFlags = readVideoCodecOperationFlagsKHR(intf, physDevice);
500
501 if (i->any({VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
502 {
503 if (!context.isDeviceFunctionalitySupported(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME))
504 {
505 if (!msgs[3])
506 {
507 if (entryCount++) str << std::endl;
508 str << INFOUSAGE("VK_EXT_video_encode_h264 not supported by device");
509 msgs[3] = true;
510 }
511 notSupported = true;
512 }
513 if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT))
514 {
515 if (!msgs[4])
516 {
517 if (entryCount++) str << std::endl;
518 str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT on device");
519 msgs[4] = true;
520 }
521 notSupported = true;
522 }
523 }
524 if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR}))
525 {
526 if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME))
527 {
528 if (!msgs[5])
529 {
530 if (entryCount++) str << std::endl;
531 str << INFOUSAGE("VK_KHR_video_decode_h264 not supported by device");
532 msgs[5] = true;
533 }
534 notSupported = true;
535 }
536 if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR))
537 {
538 if (!msgs[6])
539 {
540 if (entryCount++) str << std::endl;
541 str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR on device");
542 msgs[6] = true;
543 }
544 notSupported = true;
545 }
546 }
547 }
548 }
549 #endif // CTS_USES_VULKANSC
550
551 i = notSupported ? usageFlags.erase(i) : std::next(i);
552 }
553
554 // remove duplicates
555 for (auto i = usageFlags.begin(); i != usageFlags.end(); ++i)
556 {
557 for (auto j = std::next(i); j != usageFlags.end();)
558 j = (*i == *j) ? usageFlags.erase(j) : std::next(j);
559 }
560
561 if (usageFlags.empty())
562 {
563 log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
564 TCU_THROW(NotSupportedError, "One or more buffer usage flags not supported by device (check log for details)");
565 }
566 else
567 {
568 if (entryCount > 0)
569 {
570 log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
571 }
572 DE_ASSERT(m_instConfig.usageFlags.get());
573 m_instConfig.usageFlags->resize(usageFlags.size());
574 std::transform(usageFlags.begin(), usageFlags.end(), m_instConfig.usageFlags->begin(),
575 [](BufferUsageBits& bits){ return BufferUsageBits::makeShared(std::move(bits)); });
576 }
577 }
578
579 // check the external memory handle type bits and build instance input
580 {
581 std::vector<ExternalMemoryHandleBits> extMemHandleFlags;
582 if (m_testConfig.incExtMemTypeFlags)
583 extMemHandleFlags.push_back({AvailableExternalMemoryHandleBits.get(INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS)});
584 else
585 {
586 std::vector<VkExternalMemoryHandleTypeFlags> handleHints;
587 std::vector<ExternalMemoryHandleBits> handleFlagsTmp;
588 u::combine(handleFlagsTmp, AvailableExternalMemoryHandleBits.select<2>(true), handleHints);
589 u::mergeFlags(extMemHandleFlags, handleFlagsTmp);
590 }
591
592 DE_ASSERT(m_instConfig.extMemHandleFlags.get());
593 m_instConfig.extMemHandleFlags->resize(extMemHandleFlags.size());
594 std::transform(extMemHandleFlags.begin(), extMemHandleFlags.end(), m_instConfig.extMemHandleFlags->begin(),
595 [](ExternalMemoryHandleBits& bits){ return ExternalMemoryHandleBits::makeShared(std::move(bits)); });
596 }
597
598 if (m_testConfig.testSizeRequirements)
599 {
600 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance4"))
601 TCU_THROW(NotSupportedError, "VK_KHR_maintenance4 not supported");
602 }
603 }
604
logFailedSubtests(const std::vector<BufferCreateBitsPtr> & failCreateBits,const std::vector<BufferUsageBitsPtr> & failUsageBits,const std::vector<ExternalMemoryHandleBitsPtr> & failExtMemHandleBits) const605 void BufferMemoryRequirementsInstance::logFailedSubtests (const std::vector<BufferCreateBitsPtr>& failCreateBits,
606 const std::vector<BufferUsageBitsPtr>& failUsageBits,
607 const std::vector<ExternalMemoryHandleBitsPtr>& failExtMemHandleBits) const
608 {
609 const deUint32 flagCount = deUint32(failCreateBits.size());
610 TestLog& log = m_context.getTestContext().getLog();
611 deUint32 entries = 0;
612
613 DE_ASSERT(flagCount && flagCount == failUsageBits.size() && flagCount == failExtMemHandleBits.size());
614
615 log << TestLog::Section("Failed", "Failed subtests");
616
617 for (deUint32 i = 0; i < flagCount; ++i)
618 {
619 {
620 log << TestLog::Section("VkBufferCreateFlags", "Buffer create flags");
621 auto msg = log << TestLog::Message;
622 entries = 0;
623 for (const auto& createBit : *failCreateBits[i])
624 {
625 if (entries++) msg << " ";
626 const VkBufferCreateFlags flags = BufferCreateBits::extract(createBit);
627 if (flags == 0)
628 msg << "0";
629 else msg << getBufferCreateFlagsStr(flags);
630 }
631 msg << TestLog::EndMessage << TestLog::EndSection;
632 }
633
634 {
635 log << TestLog::Section("VkBufferUsageFlags", "Buffer usage flags");
636 auto msg = log << TestLog::Message;
637 entries = 0;
638 for (const auto& usageBit : *failUsageBits[i])
639 {
640 if (entries++) msg << " ";
641 msg << getBufferUsageFlagsStr(BufferUsageBits::extract(usageBit));
642 }
643 msg << TestLog::EndMessage << TestLog::EndSection;
644 }
645
646 {
647 log << TestLog::Section("VkExternalMemoryHandleTypeFlags", "External memory handle type flags");
648 auto msg = log << TestLog::Message;
649 entries = 0;
650 for (const auto& extMemHandleTypeBit : *failExtMemHandleBits[i])
651 {
652 if (entries++) msg << " ";
653 msg << getExternalMemoryHandleTypeFlagsStr(ExternalMemoryHandleBits::extract(extMemHandleTypeBit));
654 }
655 msg << TestLog::EndMessage << TestLog::EndSection;
656 }
657 }
658
659 log << TestLog::EndSection;
660 }
661
getBufferMemoryRequirements2(VkMemoryRequirements & result,const DeviceInterface & vkd,VkDevice device,VkBuffer buffer) const662 void BufferMemoryRequirementsInstance::getBufferMemoryRequirements2 (VkMemoryRequirements& result,
663 const DeviceInterface& vkd,
664 VkDevice device,
665 VkBuffer buffer) const
666 {
667 VkMemoryDedicatedRequirements dedicatedRequirements =
668 {
669 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, // VkStructureType sType;
670 nullptr, // const void* pNext;
671 VK_FALSE, // VkBool32 prefersDedicatedAllocation
672 VK_FALSE // VkBool32 requiresDedicatedAllocation
673 };
674
675 VkMemoryRequirements2 desiredRequirements =
676 {
677 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // VkStructureType sType
678 &dedicatedRequirements, // void* pNext
679 result // VkMemoryRequirements memoryRequirements
680 };
681
682 VkBufferMemoryRequirementsInfo2 requirementsInfo =
683 {
684 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, // VkStructureType sType
685 nullptr, // const void* pNext
686 buffer // VkBuffer buffer
687 };
688
689 vkd.getBufferMemoryRequirements2(device, &requirementsInfo, &desiredRequirements);
690
691 result = desiredRequirements.memoryRequirements;
692 }
693
getBufferMemoryRequirements(VkMemoryRequirements & result,const DeviceInterface & vkd,VkDevice device,VkBuffer buffer) const694 void BufferMemoryRequirementsInstance::getBufferMemoryRequirements (VkMemoryRequirements& result,
695 const DeviceInterface& vkd,
696 VkDevice device,
697 VkBuffer buffer) const
698 {
699 vkd.getBufferMemoryRequirements(device, buffer, &result);
700 }
701
702 template<> void*
chainVkStructure(void * pNext,const VkExternalMemoryHandleTypeFlags & handleTypes) const703 BufferMemoryRequirementsInstance::chainVkStructure<VkExternalMemoryBufferCreateInfo> (void* pNext, const VkExternalMemoryHandleTypeFlags& handleTypes) const
704 {
705 static VkExternalMemoryBufferCreateInfo memInfo{};
706 memInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
707 memInfo.pNext = pNext;
708 memInfo.handleTypes = handleTypes;
709
710 return &memInfo;
711 }
712
713 #ifndef CTS_USES_VULKANSC
chainVkStructure(void * pNext,const VkBufferUsageFlags & videoCodecUsage) const714 template<> void* BufferMemoryRequirementsInstance::chainVkStructure<VkVideoProfileListInfoKHR> (void* pNext, const VkBufferUsageFlags& videoCodecUsage) const
715 {
716 const bool encode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR);
717 const bool decode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR);
718
719 static VkVideoEncodeH264ProfileInfoEXT encodeProfile
720 {
721 VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT, // VkStructureType sType;
722 nullptr, // const void* pNext;
723 STD_VIDEO_H264_PROFILE_IDC_BASELINE // StdVideoH264ProfileIdc stdProfileIdc;
724 };
725
726 static VkVideoDecodeH264ProfileInfoKHR decodeProfile
727 {
728 VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR, // VkStructureType sType;
729 nullptr, // const void* pNext;
730 STD_VIDEO_H264_PROFILE_IDC_BASELINE, // StdVideoH264ProfileIdc stdProfileIdc;
731 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR // VkVideoDecodeH264FieldLayoutFlagsEXT fieldLayout;
732 };
733
734 static const VkVideoProfileInfoKHR videoProfiles[]
735 {
736 // encode profile
737 {
738 VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, // VkStructureType sType;
739 &encodeProfile, // void* pNext;
740 VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT, // VkVideoCodecOperationFlagBitsKHR videoCodecOperation;
741 VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR, // VkVideoChromaSubsamplingFlagsKHR chromaSubsampling;
742 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, // VkVideoComponentBitDepthFlagsKHR lumaBitDepth;
743 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR // VkVideoComponentBitDepthFlagsKHR chromaBitDepth;
744 },
745 // decode profile
746 {
747 VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, // VkStructureType sType;
748 &decodeProfile, // void* pNext;
749 VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR, // VkVideoCodecOperationFlagBitsKHR videoCodecOperation;
750 VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR, // VkVideoChromaSubsamplingFlagsKHR chromaSubsampling;
751 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, // VkVideoComponentBitDepthFlagsKHR lumaBitDepth;
752 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR // VkVideoComponentBitDepthFlagsKHR chromaBitDepth;
753 }
754 };
755 static VkVideoProfileListInfoKHR profiles;
756 profiles.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
757 profiles.pNext = pNext;
758 if (encode && decode)
759 {
760 profiles.profileCount = 2u;
761 profiles.pProfiles = videoProfiles;
762 }
763 else if (encode)
764 {
765 profiles.profileCount = 1u;
766 profiles.pProfiles = &videoProfiles[0];
767 }
768 else
769 {
770 profiles.profileCount = 1u;
771 profiles.pProfiles = &videoProfiles[1];
772 }
773 return &profiles;
774 }
775 #endif // CTS_USES_VULKANSC
776
createProtectedDevice(const Context & context)777 static Move<VkDevice> createProtectedDevice(const Context &context)
778 {
779 auto &cmdLine = context.getTestContext().getCommandLine();
780 const float queuePriority = 1.0f;
781
782 VkPhysicalDeviceProtectedMemoryFeatures protectedMemoryFeatures;
783 protectedMemoryFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
784 protectedMemoryFeatures.pNext = DE_NULL;
785 protectedMemoryFeatures.protectedMemory = VK_TRUE;
786
787 VkDeviceQueueCreateInfo queueInfo =
788 {
789 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
790 DE_NULL, // const void* pNext;
791 vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, // VkDeviceQueueCreateFlags flags;
792 context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex;
793 1u, // deUint32 queueCount;
794 &queuePriority // const float* pQueuePriorities;
795 };
796 const VkDeviceCreateInfo deviceInfo =
797 {
798 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
799 &protectedMemoryFeatures, // const void* pNext;
800 (VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
801 1u, // uint32_t queueCreateInfoCount;
802 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
803 0u, // uint32_t enabledLayerCount;
804 DE_NULL, // const char* const* ppEnabledLayerNames;
805 0u, // uint32_t enabledExtensionCount;
806 DE_NULL, // const char* const* ppEnabledExtensionNames;
807 DE_NULL // const VkPhysicalDeviceFeatures* pEnabledFeatures;
808 };
809 return createCustomDevice(cmdLine.isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceInfo);
810 }
811
iterate(void)812 TestStatus BufferMemoryRequirementsInstance::iterate (void)
813 {
814 const DeviceInterface& vkd = m_context.getDeviceInterface();
815 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
816 const Method method = m_config.useMethod2
817 ? &BufferMemoryRequirementsInstance::getBufferMemoryRequirements2
818 : &BufferMemoryRequirementsInstance::getBufferMemoryRequirements;
819
820 deUint32 passCount = 0;
821 deUint32 failCount = 0;
822 std::vector<BufferCreateBitsPtr> failCreateBits;
823 std::vector<BufferUsageBitsPtr> failUsageBits;
824 std::vector<ExternalMemoryHandleBitsPtr> failExtMemHandleBits;
825
826 Move<VkDevice> protectedDevice;
827 VkDevice device;
828 if (m_config.createBits->contains(VK_BUFFER_CREATE_PROTECTED_BIT))
829 {
830 protectedDevice = createProtectedDevice(m_context);
831 device = *protectedDevice;
832 }
833 else
834 {
835 device = m_context.getDevice();
836 }
837
838 DE_ASSERT(!m_config.createBits->empty());
839 const VkBufferCreateFlags infoCreateFlags = *m_config.createBits;
840 {
841 DE_ASSERT(!m_config.usageFlags->empty());
842 for (auto u = m_config.usageFlags->cbegin(); u != m_config.usageFlags->cend(); ++u)
843 {
844 const VkBufferUsageFlags infoUsageFlags = *(u->get());
845
846 DE_ASSERT(!m_config.extMemHandleFlags->empty());
847 for (auto m = m_config.extMemHandleFlags->cbegin(); m != m_config.extMemHandleFlags->cend(); ++m)
848 {
849 const VkExternalMemoryHandleTypeFlags handleFlags = *(m->get());
850
851 void* pNext = nullptr;
852
853 #ifndef CTS_USES_VULKANSC
854 if (m_config.fateBits->contains(BufferFateFlagBits::Video))
855 {
856 pNext = chainVkStructure<VkVideoProfileListInfoKHR>(pNext, infoUsageFlags);
857 }
858 #endif // CTS_USES_VULKANSC
859 if (m_config.incExtMemTypeFlags)
860 {
861 pNext = chainVkStructure<VkExternalMemoryBufferCreateInfo>(pNext, handleFlags);
862 }
863 VkBufferCreateInfo createInfo
864 {
865 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
866 pNext, // const void* pNext;
867 infoCreateFlags, // VkBufferCreateFlags flags;
868 4096u, // VkDeviceSize size;
869 infoUsageFlags, // VkBufferUsageFlags usage;
870 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
871 1u, // uint32_t queueFamilyIndexCount;
872 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
873 };
874
875 #ifndef CTS_USES_VULKANSC
876 if (m_config.testSizeRequirements)
877 {
878 VkPhysicalDeviceMaintenance4PropertiesKHR maintenance4Properties =
879 {
880 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR, // VkStructureType sType;
881 DE_NULL, // void* pNext;
882 0u // VkDeviceSize maxBufferSize;
883 };
884
885 VkPhysicalDeviceProperties2 physicalDeviceProperties2 =
886 {
887 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, // VkStructureType sType;
888 &maintenance4Properties, // void* pNext;
889 {}, // VkPhysicalDeviceProperties properties;
890 };
891
892 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &physicalDeviceProperties2);
893
894 const VkDeviceSize maxBufferSize = maintenance4Properties.maxBufferSize;
895 DE_ASSERT(maxBufferSize > 0);
896 VkDeviceSize N = 0;
897
898 while ((1ull << N) + 1 < maxBufferSize)
899 {
900 createInfo.size = (1ull << N) + 1;
901
902 try
903 {
904 Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);
905
906 VkMemoryRequirements reqs{};
907 (this->*method)(reqs, vkd, device, *buffer);
908
909 if (reqs.size <= static_cast<VkDeviceSize>(deAlign64(static_cast<deInt64>(createInfo.size), static_cast<deInt64>(reqs.alignment))))
910 {
911 ++passCount;
912 } else
913 {
914 ++failCount;
915 failCreateBits.emplace_back(m_config.createBits);
916 failUsageBits.emplace_back(*u);
917 failExtMemHandleBits.emplace_back(*m);
918 }
919
920 N++;
921 }
922 catch (const vk::OutOfMemoryError&)
923 {
924 break;
925 }
926 }
927
928 if (m_context.getTestContext().getWatchDog())
929 qpWatchDog_reset(m_context.getTestContext().getWatchDog());
930 }
931 else
932 #endif // CTS_USES_VULKANSC
933 {
934 Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);
935
936 VkMemoryRequirements reqs{};
937 (this->*method)(reqs, vkd, device, *buffer);
938 if (reqs.memoryTypeBits)
939 ++passCount;
940 else
941 {
942 ++failCount;
943 failCreateBits.emplace_back(m_config.createBits);
944 failUsageBits.emplace_back(*u);
945 failExtMemHandleBits.emplace_back(*m);
946 }
947 }
948 }
949 }
950 }
951
952 if (failCount)
953 {
954 logFailedSubtests(failCreateBits, failUsageBits, failExtMemHandleBits);
955 return TestStatus::fail(std::to_string(failCount));
956 }
957
958 return TestStatus::pass(std::to_string(passCount));
959 }
960
961 } // unnamed namespace
962
createBufferMemoryRequirementsTests(tcu::TestContext & testCtx)963 tcu::TestCaseGroup* createBufferMemoryRequirementsTests (tcu::TestContext& testCtx)
964 {
965 cstr nilstr = "";
966
967 struct
968 {
969 bool include;
970 cstr name;
971 } const extMemTypeFlags[] { { false, "ext_mem_flags_excluded" }, { true, "ext_mem_flags_included" } };
972
973 struct
974 {
975 bool method;
976 cstr name;
977 } const methods[]
978 {
979 { false, "method1" },
980 { true, "method2" }
981 };
982
983 std::vector<SharedPtr<BufferCreateBits>> createBitPtrs;
984 {
985 std::vector<VkBufferCreateFlags> hints;
986 std::vector<BufferCreateBits> createFlags;
987 u::combine(createFlags, AvailableBufferCreateBits, hints);
988 updateBufferCreateFlags(createFlags);
989 createBitPtrs.resize(createFlags.size());
990 std::transform(createFlags.begin(), createFlags.end(), createBitPtrs.begin(),
991 [](BufferCreateBits& bits) { return BufferCreateBits::makeShared(std::move(bits)); });
992 }
993
994 std::vector<SharedPtr<BufferFateBits>> fateBitPtrs;
995 {
996 // An excerpt above has been disabled consciously for the sake of computational complexity.
997 // Enabled block does the same things sequentially, it doesn't create cartesian product of combination of bits.
998 #if 0
999 std::vector<BufferFateFlags> hints;
1000 std::vector<BufferFateBits> bufferFateFlags;
1001 u::combine(bufferFateFlags, AvailableBufferFateBits, hints);
1002 fateBitPtrs.resize(bufferFateFlags.size());
1003 std::transform(bufferFateFlags.begin(), bufferFateFlags.end(), fateBitPtrs.begin(),
1004 [](BufferFateBits& bits) { return BufferFateBits::makeShared(std::move(bits)); });
1005 #else
1006 fateBitPtrs.resize(AvailableBufferFateBits.size());
1007 std::transform(AvailableBufferFateBits.begin(), AvailableBufferFateBits.end(), fateBitPtrs.begin(),
1008 [](const typename BufferFateBits::value_type& bit) { return BufferFateBits::makeShared(bit); });
1009 #endif
1010 }
1011
1012 auto groupRoot = new TestCaseGroup(testCtx, "buffer_memory_requirements", "vkGetBufferMemoryRequirements*(...) routines tests.");
1013 for (const auto& createBits : createBitPtrs)
1014 {
1015 auto groupCreate = new TestCaseGroup(testCtx, bitsToString(*createBits, "create_").c_str(), nilstr);
1016 for (const auto& extMemTypeFlag : extMemTypeFlags)
1017 {
1018 auto groupExtMemTypeFlags = new TestCaseGroup(testCtx, extMemTypeFlag.name, nilstr);
1019 for (const auto& method : methods)
1020 {
1021 auto groupMethod = new TestCaseGroup(testCtx, method.name, nilstr);
1022 for (const auto& fateBits : fateBitPtrs)
1023 {
1024 #ifndef CTS_USES_VULKANSC
1025 for (const auto testSizeReq : {false, true})
1026 #else
1027 const bool testSizeReq = false;
1028 #endif // CTS_USES_VULKANSC
1029 {
1030 TestConfig config;
1031 config.fateBits = fateBits;
1032 config.incExtMemTypeFlags = extMemTypeFlag.include;
1033 config.createBits = createBits;
1034 config.useMethod2 = method.method;
1035 config.testSizeRequirements = testSizeReq;
1036 groupMethod->addChild(new MemoryRequirementsTest(testCtx, ((testSizeReq ? "size_req_" : "") + bitsToString(*fateBits)).c_str(), config));
1037 }
1038 }
1039 groupExtMemTypeFlags->addChild(groupMethod);
1040 }
1041 groupCreate->addChild(groupExtMemTypeFlags);
1042 }
1043 groupRoot->addChild(groupCreate);
1044 }
1045
1046 return groupRoot;
1047 }
1048 } // api
1049 } // vkt
1050