Vulkan 着色器和资源:为什么统一而不是 Const 资源

Vulkan Shader & Resources: Why Uniform and not Const Resources

我们在c++中通常使用const表示值不变(read only),为什么在GLSL/VK 在着色器或资源定义中他们选择 uniform 这个词?不会更加一致并使用从 c/c++

借来的关键字

除此之外,着色器定义中的 uniform 关键字可能会提示编译器将这些资源附加到尽可能靠近硬件的位置,可能是 共享内存寄存器 ?不确定。

这也可能是他们在 VkSpec 中提到的原因。我们需要这些类型的资源的少量数据。例如:宇宙常数的值..等

有没有我遗漏的东西,或者一些已经过去的历史?

GPU 编程中的 Uniforms 和 C++ 中的 const 侧重于不同的东西。

C++ const 文档表明变量不打算通过某些编译器强制更改。因此,它更多地是关于使用类型系统来提高清晰度并强制执行预期用途——这对于大型项目软件工程很重要。您仍然可以使用 const_cast 或其他技巧来绕过它,并且编译器不能假设您没有这样做,因此并未严格执行。

关于制服的重要一点是它们是,嗯,制服。这意味着无论何时在绘图调用中读取它们,它们都具有相同的值。由于在单个绘制调用中可能有数百万次读取该值,这允许它被缓存,并且只缓存它的一个副本,或者它可以在着色器之前预加载到寄存器(或缓存)中运行,它可以缓存在非一致性缓存中,单个读取结果可以在内核中的所有 SIMD 通道中广播,等等。要实现这一点,内容不能改变的事实必须严格执行(使用内存别名,你现在甚至可以绕过这个,但如果你这样做,结果非常不确定)。所以 uniform 真的不是像 const 那样向其他程序员声明意图以获得软件工程的好处,而是向编译器和驱动程序声明意图,以便他们可以基于它进行优化。

D3D 使用 "const" 和 "constant buffer" 而不是统一的,所以显然有一些重叠。虽然这确实会导致说 "how many times do you update constants per frame?" 之类的话,但当你想到它时,说起来有点奇怪:)。这些值在着色器代码中是恒定的,但在 API 级别上很多不是恒定的。

这个词的词源在这里很重要。术语 "uniform" 源自 GLSL,其灵感来自 Renderman 标准的着色器术语。 In Renderman、"uniform" 用于值 "whose values are constant over whatever portion of the surface begin shaded"。这是 "varying" 的替代方法,它表示在表面上插值的值。

"Constant" 意味着值 never 改变。统一的价值观确实会改变;它们根本不会以与其他值相同的频率变化。输入值在每次调用时更改,统一值在每次绘制调用时更改,而常量值不变。请注意,在 GLSL 中,const 通常表示 "compile-time constant":一个在编译时设置且永远不会更改的值。

Vulkan 中的统一变量最终来自存在于着色器外部的资源。缓冲区提供的统一变量块,推送常量状态提供的推送常量中的制服都是外部资源,由用户设置。这与拥有编译时常量结构是一个根本不同的概念。

由于它不同于常量结构,因此需要不同的术语来请求它。