vk::DeviceQueueCreateFlags() 实际上做了什么?

What does vk::DeviceQueueCreateFlags() actually do?

初始化这个结构的类似 C 的方法是:

VkDeviceQueueCreateInfo queueCreateInfo = {};
    queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    queueCreateInfo.queueFamilyIndex = queueFamily;
    queueCreateInfo.queueCount = 1;
    queueCreateInfo.pQueuePriorities = &queuePriority;

使用和滥用 vulkan.hpp header 的 C++ 方式是:

vk::DeviceQueueCreateInfo deviceQueueCreateInfo(vk::DeviceQueueCreateFlags(), static_cast<uint32_t>(graphicsQueueFamilyIndex), 1, &queuePriority);

看来函数里面封装了很多工作vk::DeviceQueueCreateFlags().

然而,用我的编辑器查看源代码并没有揭示任何有用的信息。我希望有更多经验的人可以提供一些有关该功能正在做什么的信息。

它是 vk::Flags 的别名,它是在类型安全庄园中处理 Vulkan 位域的模板。

您希望枚举是类型安全的;您不希望隐式转换 to/from 整数。所以在 C++ 中,您可以通过将枚举定义为 enum class.

来实现

这对于常规枚举来说很好。但是位域是特殊的;它们是来自特定枚举的枚举数的组合。典型的 post-C++11 解决方案是只给枚举类型重载运算符,这样您就可以将 &| 应用于枚举类型本身。

就个人而言,这个解决方案总是让我感到不快。对我来说,强枚举类型应该包含 一个 枚举值,而不是其中的几个。因此,使用运算符重载来有效地允许枚举值说谎并不适合我。

显然我并不孤单,因为 vulkan.hpp 的作者选择了不同的解决方案。他们创建了一个模板 class vk::Flags,它有两个模板参数。其中之一是包含所有有效位标志的枚举。第二个参数是"enumeration",表示多个标志的连接。 vulkan.xml 规范文件真正理解的是:包含可能位的字段与作为位聚合的字段之间的区别。

vk::Flags 可以从位域中得到位,您可以通过一些按位运算符使用该位域中的位来操作它。并且它可以隐式转换为表示位聚合的类型。

所以 DeviceQueueCreateInfo 只是 Flags<DeviceQueueCreateFlagBits, VkDeviceQueueCreateFlags> 的别名,它是一个位域,它获取设备创建位并将它们聚合到标志聚合中。