什么是vulkan的"推力常数"?

whn*_*whn 18 vulkan

我查看了一堆关于推送常量的教程,暗示可能的好处,但我从未见过,即使在Vulkan文档中,实际上是什么"推动常数"......我不明白他们应该是什么,以及推动常数的目的是什么.我能找到的最接近的是这篇文章,遗憾的是它不会问它们是什么,但是它们和另一个概念之间有什么不同,并没有帮助我.

什么是推动常数,它为什么存在以及它用于什么?它的名字来自哪里?

Ekz*_*uzy 16

推送常量是一种快速向着色器提供少量统一数据的方法.它应该比UBO快得多,但数据的大小有一个巨大的限制 - 规范需要128个字节才能用于推送恒定范围.硬件供应商可能支持更多,但与其他方式相比,它仍然很少(例如256字节).

因为推送常量比其他描述符(通过我们向着色器提供数据的资源)快得多,所以它们便于用于在绘制调用之间改变的数据,例如转换矩阵.

从着色器的角度来看,它们是通过layout( push_constant )限定符和统一数据块声明的.例如:

layout( push_constant ) uniform ColorBlock {
  vec4 Color;
} PushConstant;
Run Code Online (Sandbox Code Playgroud)

从应用程序的角度来看,如果着色器要使用推送常量,则必须在创建管道布局期间指定它们.然后vkCmdPushConstants()必须将命令记录到命令缓冲区中.此函数包含一个指向内存的指针,应从中复制推送常量范围的数据.

给定管道的不同着色器阶段可以使用相同的推动常数块(类似于UBO)或整个范围的较小部分.但是,重要的是,每个着色器阶段只能使用一个推动常量块.但它可以包含多个成员.另一个重要的事情是总数据大小(使用推送常量的所有着色器阶段)必须符合大小约束.所以约束不是每个阶段而是整个范围.

Vulkan Cookbook的存储库中有一个示例,显示了一个简单的推送常量使用场景.Sascha Willems的Vulkan示例还包含一个示例,说明如何使用推式常量.

  • 在着色器中您只能读取存储在推送常量块中的值.因此,从着色器角度看它们是恒定的(类似于统一缓冲区中的数据).为什么叫做推?由于它们由硬件管理 - 据我所知,值存储在命令缓冲存储器中.因此,它们会沿着其他命令缓冲区数据推送到硬件. (6认同)
  • @snb Vulkan Cookbook 中的推送常量示例可在此处获取:https://github.com/PacktPublishing/Vulkan-Cookbook/blob/master/Samples/Source%20Files/Other/07-Using_Push_Constants/main.cpp(称为“07 - 使用推送常量”)。推送常量使用“vkCmdPushConstant()”函数进行更新(填充数据),您可以为该函数提供一个指向内存的指针,其中包含应提供给着色器的数据(我已经更新了我的答案)。至于重新创建命令缓冲区 - 您不必重新创建它们,重新录制就足够了(除非您询问其他问题)。 (2认同)