Graphics 为什么VkShaderStageFlagBits是位掩码?
在Vulkan中,您可以将Graphics 为什么VkShaderStageFlagBits是位掩码?,graphics,bit-manipulation,bit,vulkan,bitmask,Graphics,Bit Manipulation,Bit,Vulkan,Bitmask,在Vulkan中,您可以将VkPipelineShaderStageCreateInfo指定给VkGraphicsPipelineCreateInfo结构,并且假设每个着色器阶段(例如顶点和片段着色器)都有一个VkPipelineShaderStageCreateInfo 那么,为什么字段stage字段的类型是vkShaderStageFlagBits,这仅仅是因为它更接近于某种Vulkan约定 我的困惑是,我被引导相信,以这种方式使用位掩码的唯一原因是,如果需要将位组合在一起。(例如,对于所有
VkPipelineShaderStageCreateInfo
指定给VkGraphicsPipelineCreateInfo
结构,并且假设每个着色器阶段(例如顶点和片段着色器)都有一个VkPipelineShaderStageCreateInfo
那么,为什么字段stage
字段的类型是vkShaderStageFlagBits
,这仅仅是因为它更接近于某种Vulkan约定
我的困惑是,我被引导相信,以这种方式使用位掩码的唯一原因是,如果需要将位组合在一起。(例如,对于所有Vulkan结构中的generalflags
字段)。我试图找到这个问题的答案,所以我查看了Vulkan规范,这让我更加困惑!这是因为它们有两个位VK\u SHADER\u STAGE\u ALL\u GRAPHICS
和VK\u SHADER\u STAGE\u ALL
,它们被定义为:
VK_SHADER_STAGE_ALL_GRAPHICS是一个位的组合,用作速记,用于指定上面定义的所有图形阶段(不包括计算阶段)
VK_SHADER_STAGE_ALL是一个位的组合,用作简写,用于指定设备支持的所有着色器阶段,包括扩展引入的所有附加阶段
如果它们应该是指定所有位的“速记”,这是否意味着一个着色器阶段应该能够表示所有阶段的一个版本
提前谢谢 确切地说,这主要是为了保持api的一致性。VkShaderStageFlagBits用于几个位置,其中位掩码比管道创建时更有意义 有意义的一个示例是描述符集布局绑定,其中使用标志掩码指定哪些阶段可以访问描述符(采样器、统一缓冲区对象等)
因此,如果希望一个UBO可以从顶点和碎片阶段访问,另一个UBO可以从几何体和细分阶段访问,那么在设置
VkDescriptorSetLayoutBinding
时,应该使用不同的阶段标志位组合。管道状态组合在这里非常常见。Vulkan使用类型为Vk*标志位的字段(例如VkShaderStageFlagBits
),而此时正好需要一个定义值,并使用相应的Vk*标志
类型(始终是VkFlags
的typedef,它只是uint32\u t
的typedef(例如typedef VkFlags VkShaderStageFlags
),当预期的定义值组合为零、一个或多个时
原因有两个:
它给出了一个信号(尽管很微妙),表明是否只需要一个值,或者需要一些值的组合
许多编译器在将位值组合分配给枚举类型的字段时会发出警告,这在实践中有助于强制执行(1)。这是因为要对枚举值执行逐位操作,它们首先升级为整数类型,结果是整数类型,大多数编译器的典型设置会产生警告(通常升级为错误)执行从整数到枚举类型的隐式转换时,因为整数可能不是枚举值之一
因此VkPipelineShaderStageCreateInfo::stage
是VkShaderStageFlagBits
,因为只有一个着色器阶段在那里有效,如果您尝试将其设置为类似VK_着色器_阶段(顶点)位| VK_着色器(阶段)片段(位
之类的愚蠢设置,您可能会收到警告
但是VkDescriptorSetLayoutBinding::stageFlags
是VkShaderStageFlags
,因为它很常见,并且应该包含多个阶段,如果将其设置为VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT
,则不会收到编译器警告,请注意,因为我还没有学过ab输出管道布局或描述符集。感谢示例;)!!我相信您指的是VkPipelineShaderStageCreateInfo::stage
,而不是VkPipelineShaderStageCreateInfo::flags
Woops,是的,已修复。