初始化此结构的类似C的方法是:
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = queueFamily;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &queuePriority;
使用和滥用vulkan.hpp标头C++方法是:
vk::DeviceQueueCreateInfo deviceQueueCreateInfo(vk::DeviceQueueCreateFlags(), static_cast<uint32_t>(graphicsQueueFamilyIndex), 1, &queuePriority);
似乎很多工作都封装在函数vk::DeviceQueueCreateFlags()
中。
但是,与我的编辑器一起查看源代码并没有发现任何有用的东西。我希望有更多经验的人可以提供一些关于该功能正在做什么的信息。
它是vk::Flags
的别名,它是在类型安全庄园中处理 Vulkan 位域的模板。
您希望枚举是类型安全的;您不希望与整数进行隐式转换。因此,在C++中,您可以通过将枚举定义为enum class
来执行此操作。
这对于常规枚举来说很好。但是位域很特殊;它们是特定枚举中的枚举器的组合。典型的 C++11 后解决方案是只提供枚举类型重载运算符,以便可以将&
和|
应用于枚举类型本身。
就个人而言,这个解决方案总是以错误的方式摩擦我。对我来说,强枚举类型应该保存其中一个枚举值,而不是几个枚举值。因此,使用运算符重载来有效地允许枚举值撒谎对我来说并不合适。
显然,我并不孤单,因为vulkan.hpp
的作者选择了不同的解决方案。他们创建了一个模板类vk::Flags
,它接受两个模板参数。其中之一是包含所有有效位标志的枚举。第二个参数是表示多个标志串联的"枚举"。这是 vulkan.xml 规范文件实际上理解的东西:包含可能位的字段和作为位聚合的字段之间的区别。
vk::Flags
可以从位域中获取位,并且可以通过一些按位运算符使用该位域中的位进行操作。它可以隐式转换为表示位聚合的类型。
所以DeviceQueueCreateInfo
只是Flags<DeviceQueueCreateFlagBits, VkDeviceQueueCreateFlags>
的别名,它是一个位域,它接受设备创建位并将它们聚合到标志聚合中。