Graphics 为什么VkShaderStageFlagBits是位掩码?

Graphics 为什么VkShaderStageFlagBits是位掩码?,graphics,bit-manipulation,bit,vulkan,bitmask,Graphics,Bit Manipulation,Bit,Vulkan,Bitmask,在Vulkan中,您可以将VkPipelineShaderStageCreateInfo指定给VkGraphicsPipelineCreateInfo结构,并且假设每个着色器阶段(例如顶点和片段着色器)都有一个VkPipelineShaderStageCreateInfo 那么,为什么字段stage字段的类型是vkShaderStageFlagBits,这仅仅是因为它更接近于某种Vulkan约定 我的困惑是,我被引导相信,以这种方式使用位掩码的唯一原因是,如果需要将位组合在一起。(例如,对于所有

在Vulkan中,您可以将
VkPipelineShaderStageCreateInfo
指定给
VkGraphicsPipelineCreateInfo
结构,并且假设每个着色器阶段(例如顶点和片段着色器)都有一个
VkPipelineShaderStageCreateInfo

那么,为什么字段
stage
字段的类型是
vkShaderStageFlagBits
,这仅仅是因为它更接近于某种Vulkan约定

我的困惑是,我被引导相信,以这种方式使用位掩码的唯一原因是,如果需要将位组合在一起。(例如,对于所有Vulkan结构中的general
flags
字段)。我试图找到这个问题的答案,所以我查看了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,是的,已修复。