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::__anon384aa0210111::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)
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::__anon384aa0210111::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 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
379
380 if (m_testConfig.useMethod2)
381 context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
382
383 VkPhysicalDeviceProtectedMemoryFeatures protectedMemFeatures
384 {
385 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES, // VkStructureType sType;
386 nullptr, // void* pNext;
387 VK_FALSE // VkBool32 protectedMemory;
388 };
389 VkPhysicalDeviceFeatures2 extFeatures
390 {
391 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // VkStructureType sType;
392 &protectedMemFeatures, // void* pNext;
393 {} // VkPhysicalDeviceFeatures features;
394 };
395 intf.getPhysicalDeviceFeatures2(physDevice, &extFeatures);
396
397 const VkPhysicalDeviceFeatures& features = extFeatures.features;
398 const VkBool32& protectedMemFeatureEnabled = protectedMemFeatures.protectedMemory;
399
400 // check the creating bits
401 {
402 std::ostringstream str;
403 bool notSupported = false;
404 const auto& createBits = *m_testConfig.createBits;
405
406 if (createBits.contains(VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && (VK_FALSE == features.sparseBinding))
407 {
408 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_BINDING_BIT));
409 notSupported = true;
410 }
411 if (createBits.contains(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && (VK_FALSE == features.sparseResidencyBuffer))
412 {
413 if (notSupported) str << std::endl;
414 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT));
415 notSupported = true;
416 }
417 if (createBits.contains(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && (VK_FALSE == features.sparseResidencyAliased))
418 {
419 if (notSupported) str << std::endl;
420 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT));
421 notSupported = true;
422 }
423 if (createBits.contains(VK_BUFFER_CREATE_PROTECTED_BIT) && (VK_FALSE == protectedMemFeatureEnabled))
424 {
425 if (notSupported) str << std::endl;
426 str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_PROTECTED_BIT));
427 notSupported = true;
428 }
429 if (notSupported)
430 {
431 log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
432 TCU_THROW(NotSupportedError, "One or more create buffer flags not supported by device (check log for details)");
433 }
434 }
435
436 // check the usage bits and build instance input
437 {
438 std::vector<BufferUsageBits> usageFlags;
439 for (const auto& bit : *m_testConfig.fateBits)
440 {
441 auto fate = m_testConfig.fateBits->extract(bit);
442 std::vector<VkBufferUsageFlags> usageHints;
443 std::vector<BufferUsageBits> usageFlagsTmp;
444 u::combine(usageFlagsTmp, AvailableBufferUsageBits.select<1>(fate), usageHints);
445 u::mergeFlags(usageFlags, usageFlagsTmp);
446 }
447
448 std::ostringstream str;
449 std::array<bool, 7> msgs;
450 bool notSupported = false;
451 int entryCount = 0;
452 msgs.fill(false);
453
454 for (auto i = usageFlags.begin(); i != usageFlags.end();)
455 {
456 notSupported = false;
457
458 #ifndef CTS_USES_VULKANSC
459 if (i->any({VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
460 VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR})
461 && !context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
462 {
463 if (!msgs[0])
464 {
465 if (entryCount++) str << std::endl;
466 str << INFOUSAGE("VK_KHR_acceleration_structure not supported by device");
467 msgs[0] = true;
468 }
469 notSupported = true;
470 }
471 #endif // CTS_USES_VULKANSC
472
473 if (i->contains(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
474 && !context.isBufferDeviceAddressSupported())
475 {
476 if (!msgs[1])
477 {
478 if (entryCount++) str << std::endl;
479 str << INFOUSAGE("VK_EXT_buffer_device_address not supported by device");
480 msgs[1] = true;
481 }
482 notSupported = true;
483 }
484
485 #ifndef CTS_USES_VULKANSC
486 if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR,
487 VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
488 {
489 if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME))
490 {
491 if (!msgs[2])
492 {
493 if (entryCount++) str << std::endl;
494 str << INFOUSAGE("VK_EXT_video_queue not supported by device");
495 msgs[2] = true;
496 }
497 notSupported = true;
498 }
499 else
500 {
501 const VkVideoCodecOperationFlagsKHR videoFlags = readVideoCodecOperationFlagsKHR(intf, physDevice);
502
503 if (i->any({VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
504 {
505 if (!context.isDeviceFunctionalitySupported(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME))
506 {
507 if (!msgs[3])
508 {
509 if (entryCount++) str << std::endl;
510 str << INFOUSAGE("VK_EXT_video_encode_h264 not supported by device");
511 msgs[3] = true;
512 }
513 notSupported = true;
514 }
515 if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT))
516 {
517 if (!msgs[4])
518 {
519 if (entryCount++) str << std::endl;
520 str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT on device");
521 msgs[4] = true;
522 }
523 notSupported = true;
524 }
525 }
526 if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR}))
527 {
528 if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME))
529 {
530 if (!msgs[5])
531 {
532 if (entryCount++) str << std::endl;
533 str << INFOUSAGE("VK_KHR_video_decode_h264 not supported by device");
534 msgs[5] = true;
535 }
536 notSupported = true;
537 }
538 if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR))
539 {
540 if (!msgs[6])
541 {
542 if (entryCount++) str << std::endl;
543 str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR on device");
544 msgs[6] = true;
545 }
546 notSupported = true;
547 }
548 }
549 }
550 }
551 #endif // CTS_USES_VULKANSC
552
553 i = notSupported ? usageFlags.erase(i) : std::next(i);
554 }
555
556 // remove duplicates
557 for (auto i = usageFlags.begin(); i != usageFlags.end(); ++i)
558 {
559 for (auto j = std::next(i); j != usageFlags.end();)
560 j = (*i == *j) ? usageFlags.erase(j) : std::next(j);
561 }
562
563 if (usageFlags.empty())
564 {
565 log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
566 TCU_THROW(NotSupportedError, "One or more buffer usage flags not supported by device (check log for details)");
567 }
568 else
569 {
570 if (entryCount > 0)
571 {
572 log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
573 }
574 DE_ASSERT(m_instConfig.usageFlags.get());
575 m_instConfig.usageFlags->resize(usageFlags.size());
576 std::transform(usageFlags.begin(), usageFlags.end(), m_instConfig.usageFlags->begin(),
577 [](BufferUsageBits& bits){ return BufferUsageBits::makeShared(std::move(bits)); });
578 }
579 }
580
581 // check the external memory handle type bits and build instance input
582 {
583 std::vector<ExternalMemoryHandleBits> extMemHandleFlags;
584 if (m_testConfig.incExtMemTypeFlags)
585 extMemHandleFlags.push_back({AvailableExternalMemoryHandleBits.get(INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS)});
586 else
587 {
588 std::vector<VkExternalMemoryHandleTypeFlags> handleHints;
589 std::vector<ExternalMemoryHandleBits> handleFlagsTmp;
590 u::combine(handleFlagsTmp, AvailableExternalMemoryHandleBits.select<2>(true), handleHints);
591 u::mergeFlags(extMemHandleFlags, handleFlagsTmp);
592 }
593
594 DE_ASSERT(m_instConfig.extMemHandleFlags.get());
595 m_instConfig.extMemHandleFlags->resize(extMemHandleFlags.size());
596 std::transform(extMemHandleFlags.begin(), extMemHandleFlags.end(), m_instConfig.extMemHandleFlags->begin(),
597 [](ExternalMemoryHandleBits& bits){ return ExternalMemoryHandleBits::makeShared(std::move(bits)); });
598 }
599
600 if (m_testConfig.testSizeRequirements)
601 {
602 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance4"))
603 TCU_THROW(NotSupportedError, "VK_KHR_maintenance4 not supported");
604 }
605 }
606
logFailedSubtests(const std::vector<BufferCreateBitsPtr> & failCreateBits,const std::vector<BufferUsageBitsPtr> & failUsageBits,const std::vector<ExternalMemoryHandleBitsPtr> & failExtMemHandleBits) const607 void BufferMemoryRequirementsInstance::logFailedSubtests (const std::vector<BufferCreateBitsPtr>& failCreateBits,
608 const std::vector<BufferUsageBitsPtr>& failUsageBits,
609 const std::vector<ExternalMemoryHandleBitsPtr>& failExtMemHandleBits) const
610 {
611 const deUint32 flagCount = deUint32(failCreateBits.size());
612 TestLog& log = m_context.getTestContext().getLog();
613 deUint32 entries = 0;
614
615 DE_ASSERT(flagCount && flagCount == failUsageBits.size() && flagCount == failExtMemHandleBits.size());
616
617 log << TestLog::Section("Failed", "Failed subtests");
618
619 for (deUint32 i = 0; i < flagCount; ++i)
620 {
621 {
622 log << TestLog::Section("VkBufferCreateFlags", "Buffer create flags");
623 auto msg = log << TestLog::Message;
624 entries = 0;
625 for (const auto& createBit : *failCreateBits[i])
626 {
627 if (entries++) msg << " ";
628 const VkBufferCreateFlags flags = BufferCreateBits::extract(createBit);
629 if (flags == 0)
630 msg << "0";
631 else msg << getBufferCreateFlagsStr(flags);
632 }
633 msg << TestLog::EndMessage << TestLog::EndSection;
634 }
635
636 {
637 log << TestLog::Section("VkBufferUsageFlags", "Buffer usage flags");
638 auto msg = log << TestLog::Message;
639 entries = 0;
640 for (const auto& usageBit : *failUsageBits[i])
641 {
642 if (entries++) msg << " ";
643 msg << getBufferUsageFlagsStr(BufferUsageBits::extract(usageBit));
644 }
645 msg << TestLog::EndMessage << TestLog::EndSection;
646 }
647
648 {
649 log << TestLog::Section("VkExternalMemoryHandleTypeFlags", "External memory handle type flags");
650 auto msg = log << TestLog::Message;
651 entries = 0;
652 for (const auto& extMemHandleTypeBit : *failExtMemHandleBits[i])
653 {
654 if (entries++) msg << " ";
655 msg << getExternalMemoryHandleTypeFlagsStr(ExternalMemoryHandleBits::extract(extMemHandleTypeBit));
656 }
657 msg << TestLog::EndMessage << TestLog::EndSection;
658 }
659 }
660
661 log << TestLog::EndSection;
662 }
663
getBufferMemoryRequirements2(VkMemoryRequirements & result,const DeviceInterface & vkd,VkDevice device,VkBuffer buffer) const664 void BufferMemoryRequirementsInstance::getBufferMemoryRequirements2 (VkMemoryRequirements& result,
665 const DeviceInterface& vkd,
666 VkDevice device,
667 VkBuffer buffer) const
668 {
669 VkMemoryDedicatedRequirements dedicatedRequirements =
670 {
671 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, // VkStructureType sType;
672 nullptr, // const void* pNext;
673 VK_FALSE, // VkBool32 prefersDedicatedAllocation
674 VK_FALSE // VkBool32 requiresDedicatedAllocation
675 };
676
677 VkMemoryRequirements2 desiredRequirements =
678 {
679 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // VkStructureType sType
680 &dedicatedRequirements, // void* pNext
681 result // VkMemoryRequirements memoryRequirements
682 };
683
684 VkBufferMemoryRequirementsInfo2 requirementsInfo =
685 {
686 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, // VkStructureType sType
687 nullptr, // const void* pNext
688 buffer // VkBuffer buffer
689 };
690
691 vkd.getBufferMemoryRequirements2(device, &requirementsInfo, &desiredRequirements);
692
693 result = desiredRequirements.memoryRequirements;
694 }
695
getBufferMemoryRequirements(VkMemoryRequirements & result,const DeviceInterface & vkd,VkDevice device,VkBuffer buffer) const696 void BufferMemoryRequirementsInstance::getBufferMemoryRequirements (VkMemoryRequirements& result,
697 const DeviceInterface& vkd,
698 VkDevice device,
699 VkBuffer buffer) const
700 {
701 vkd.getBufferMemoryRequirements(device, buffer, &result);
702 }
703
704 template<> void*
chainVkStructure(void * pNext,const VkExternalMemoryHandleTypeFlags & handleTypes) const705 BufferMemoryRequirementsInstance::chainVkStructure<VkExternalMemoryBufferCreateInfo> (void* pNext, const VkExternalMemoryHandleTypeFlags& handleTypes) const
706 {
707 static VkExternalMemoryBufferCreateInfo memInfo{};
708 memInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
709 memInfo.pNext = pNext;
710 memInfo.handleTypes = handleTypes;
711
712 return &memInfo;
713 }
714
715 #ifndef CTS_USES_VULKANSC
chainVkStructure(void * pNext,const VkBufferUsageFlags & videoCodecUsage) const716 template<> void* BufferMemoryRequirementsInstance::chainVkStructure<VkVideoProfileListInfoKHR> (void* pNext, const VkBufferUsageFlags& videoCodecUsage) const
717 {
718 const bool encode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR);
719 const bool decode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR);
720
721 static VkVideoEncodeH264ProfileInfoEXT encodeProfile
722 {
723 VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT, // VkStructureType sType;
724 nullptr, // const void* pNext;
725 STD_VIDEO_H264_PROFILE_IDC_BASELINE // StdVideoH264ProfileIdc stdProfileIdc;
726 };
727
728 static VkVideoDecodeH264ProfileInfoKHR decodeProfile
729 {
730 VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR, // VkStructureType sType;
731 nullptr, // const void* pNext;
732 STD_VIDEO_H264_PROFILE_IDC_BASELINE, // StdVideoH264ProfileIdc stdProfileIdc;
733 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR // VkVideoDecodeH264FieldLayoutFlagsEXT fieldLayout;
734 };
735
736 static const VkVideoProfileInfoKHR videoProfiles[]
737 {
738 // encode profile
739 {
740 VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, // VkStructureType sType;
741 &encodeProfile, // void* pNext;
742 VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT, // VkVideoCodecOperationFlagBitsKHR videoCodecOperation;
743 VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR, // VkVideoChromaSubsamplingFlagsKHR chromaSubsampling;
744 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, // VkVideoComponentBitDepthFlagsKHR lumaBitDepth;
745 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR // VkVideoComponentBitDepthFlagsKHR chromaBitDepth;
746 },
747 // decode profile
748 {
749 VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, // VkStructureType sType;
750 &decodeProfile, // void* pNext;
751 VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR, // VkVideoCodecOperationFlagBitsKHR videoCodecOperation;
752 VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR, // VkVideoChromaSubsamplingFlagsKHR chromaSubsampling;
753 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, // VkVideoComponentBitDepthFlagsKHR lumaBitDepth;
754 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR // VkVideoComponentBitDepthFlagsKHR chromaBitDepth;
755 }
756 };
757 static VkVideoProfileListInfoKHR profiles;
758 profiles.sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
759 profiles.pNext = pNext;
760 if (encode && decode)
761 {
762 profiles.profileCount = 2u;
763 profiles.pProfiles = videoProfiles;
764 }
765 else if (encode)
766 {
767 profiles.profileCount = 1u;
768 profiles.pProfiles = &videoProfiles[0];
769 }
770 else
771 {
772 profiles.profileCount = 1u;
773 profiles.pProfiles = &videoProfiles[1];
774 }
775 return &profiles;
776 }
777 #endif // CTS_USES_VULKANSC
778
createProtectedDevice(const Context & context)779 static Move<VkDevice> createProtectedDevice(const Context &context)
780 {
781 auto &cmdLine = context.getTestContext().getCommandLine();
782 const float queuePriority = 1.0f;
783
784 VkPhysicalDeviceProtectedMemoryFeatures protectedMemoryFeatures;
785 protectedMemoryFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
786 protectedMemoryFeatures.pNext = DE_NULL;
787 protectedMemoryFeatures.protectedMemory = VK_TRUE;
788
789 VkDeviceQueueCreateInfo queueInfo =
790 {
791 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
792 DE_NULL, // const void* pNext;
793 vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT, // VkDeviceQueueCreateFlags flags;
794 context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex;
795 1u, // deUint32 queueCount;
796 &queuePriority // const float* pQueuePriorities;
797 };
798 const VkDeviceCreateInfo deviceInfo =
799 {
800 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
801 &protectedMemoryFeatures, // const void* pNext;
802 (VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
803 1u, // uint32_t queueCreateInfoCount;
804 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
805 0u, // uint32_t enabledLayerCount;
806 DE_NULL, // const char* const* ppEnabledLayerNames;
807 0u, // uint32_t enabledExtensionCount;
808 DE_NULL, // const char* const* ppEnabledExtensionNames;
809 DE_NULL // const VkPhysicalDeviceFeatures* pEnabledFeatures;
810 };
811 return createCustomDevice(cmdLine.isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceInfo);
812 }
813
iterate(void)814 TestStatus BufferMemoryRequirementsInstance::iterate (void)
815 {
816 const DeviceInterface& vkd = m_context.getDeviceInterface();
817 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
818 const Method method = m_config.useMethod2
819 ? &BufferMemoryRequirementsInstance::getBufferMemoryRequirements2
820 : &BufferMemoryRequirementsInstance::getBufferMemoryRequirements;
821
822 deUint32 passCount = 0;
823 deUint32 failCount = 0;
824 std::vector<BufferCreateBitsPtr> failCreateBits;
825 std::vector<BufferUsageBitsPtr> failUsageBits;
826 std::vector<ExternalMemoryHandleBitsPtr> failExtMemHandleBits;
827
828 Move<VkDevice> protectedDevice;
829 VkDevice device;
830 if (m_config.createBits->contains(VK_BUFFER_CREATE_PROTECTED_BIT))
831 {
832 protectedDevice = createProtectedDevice(m_context);
833 device = *protectedDevice;
834 }
835 else
836 {
837 device = m_context.getDevice();
838 }
839
840 DE_ASSERT(!m_config.createBits->empty());
841 const VkBufferCreateFlags infoCreateFlags = *m_config.createBits;
842 {
843 DE_ASSERT(!m_config.usageFlags->empty());
844 for (auto u = m_config.usageFlags->cbegin(); u != m_config.usageFlags->cend(); ++u)
845 {
846 const VkBufferUsageFlags infoUsageFlags = *(u->get());
847
848 DE_ASSERT(!m_config.extMemHandleFlags->empty());
849 for (auto m = m_config.extMemHandleFlags->cbegin(); m != m_config.extMemHandleFlags->cend(); ++m)
850 {
851 const VkExternalMemoryHandleTypeFlags handleFlags = *(m->get());
852
853 void* pNext = nullptr;
854
855 #ifndef CTS_USES_VULKANSC
856 if (m_config.fateBits->contains(BufferFateFlagBits::Video))
857 {
858 pNext = chainVkStructure<VkVideoProfileListInfoKHR>(pNext, infoUsageFlags);
859 }
860 #endif // CTS_USES_VULKANSC
861 if (m_config.incExtMemTypeFlags)
862 {
863 pNext = chainVkStructure<VkExternalMemoryBufferCreateInfo>(pNext, handleFlags);
864 }
865 VkBufferCreateInfo createInfo
866 {
867 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
868 pNext, // const void* pNext;
869 infoCreateFlags, // VkBufferCreateFlags flags;
870 4096u, // VkDeviceSize size;
871 infoUsageFlags, // VkBufferUsageFlags usage;
872 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
873 1u, // uint32_t queueFamilyIndexCount;
874 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
875 };
876
877 #ifndef CTS_USES_VULKANSC
878 if (m_config.testSizeRequirements)
879 {
880 VkPhysicalDeviceMaintenance4PropertiesKHR maintenance4Properties =
881 {
882 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR, // VkStructureType sType;
883 DE_NULL, // void* pNext;
884 0u // VkDeviceSize maxBufferSize;
885 };
886
887 VkPhysicalDeviceProperties2 physicalDeviceProperties2 =
888 {
889 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, // VkStructureType sType;
890 &maintenance4Properties, // void* pNext;
891 {}, // VkPhysicalDeviceProperties properties;
892 };
893
894 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &physicalDeviceProperties2);
895
896 const VkDeviceSize maxBufferSize = maintenance4Properties.maxBufferSize;
897 DE_ASSERT(maxBufferSize > 0);
898 VkDeviceSize N = 0;
899
900 while ((1ull << N) + 1 < maxBufferSize)
901 {
902 createInfo.size = (1ull << N) + 1;
903
904 try
905 {
906 Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);
907
908 VkMemoryRequirements reqs{};
909 (this->*method)(reqs, vkd, device, *buffer);
910
911 if (reqs.size <= static_cast<VkDeviceSize>(deAlign64(static_cast<deInt64>(createInfo.size), static_cast<deInt64>(reqs.alignment))))
912 {
913 ++passCount;
914 } else
915 {
916 ++failCount;
917 failCreateBits.emplace_back(m_config.createBits);
918 failUsageBits.emplace_back(*u);
919 failExtMemHandleBits.emplace_back(*m);
920 }
921
922 N++;
923 }
924 catch (const vk::OutOfMemoryError&)
925 {
926 break;
927 }
928 }
929
930 if (m_context.getTestContext().getWatchDog())
931 qpWatchDog_reset(m_context.getTestContext().getWatchDog());
932 }
933 else
934 #endif // CTS_USES_VULKANSC
935 {
936 Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);
937
938 VkMemoryRequirements reqs{};
939 (this->*method)(reqs, vkd, device, *buffer);
940 if (reqs.memoryTypeBits)
941 ++passCount;
942 else
943 {
944 ++failCount;
945 failCreateBits.emplace_back(m_config.createBits);
946 failUsageBits.emplace_back(*u);
947 failExtMemHandleBits.emplace_back(*m);
948 }
949 }
950 }
951 }
952 }
953
954 if (failCount)
955 {
956 logFailedSubtests(failCreateBits, failUsageBits, failExtMemHandleBits);
957 return TestStatus::fail(std::to_string(failCount));
958 }
959
960 return TestStatus::pass(std::to_string(passCount));
961 }
962
963 } // unnamed namespace
964
createBufferMemoryRequirementsTests(tcu::TestContext & testCtx)965 tcu::TestCaseGroup* createBufferMemoryRequirementsTests (tcu::TestContext& testCtx)
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");
1013 for (const auto& createBits : createBitPtrs)
1014 {
1015 auto groupCreate = new TestCaseGroup(testCtx, bitsToString(*createBits, "create_").c_str());
1016 for (const auto& extMemTypeFlag : extMemTypeFlags)
1017 {
1018 auto groupExtMemTypeFlags = new TestCaseGroup(testCtx, extMemTypeFlag.name);
1019 for (const auto& method : methods)
1020 {
1021 auto groupMethod = new TestCaseGroup(testCtx, method.name);
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