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