我们通常在c ++中使用 const 来暗示值不会改变(只读),为什么在着色器或资源定义中的GLSL / VK中他们选择了字统一? Wodn更加一致,并使用从 c / c ++
借来的关键字除此之外,着色器定义中的uniform关键字可能会为编译器提供线索,使这些资源尽可能靠近硬件附加,可能是共享内存或寄存器?不确定。
这也可能是他们在VkSpec中提到的原因。我们需要为这些类型的资源提供少量数据。例如:宇宙常数的值......等等。
我缺少什么,或者有些历史消失了吗?
答案 0 :(得分:2)
GPU编程中的制服和C ++中的const都集中在不同的东西上。
C ++ const文档表明变量不打算在某些编译器实现的情况下进行更改。因此,它更多地是关于使用类型系统来提高清晰度和实施预期用途 - 这对于大型项目软件工程非常重要。你仍然可以使用const_cast或其他技巧解决它,并且编译器不能假设你没有,所以它没有严格执行。
关于制服的重要一点是,他们是好的,均匀的。这意味着只要在绘制调用中读取它们,它们就具有相同的值。由于在单个绘制调用中可能有数百到数百万次读取该值,因此可以对其进行高速缓存,只需缓存一个副本,或者可以在着色器运行之前将其预加载到寄存器(或缓存)中,它可以缓存在非连贯的缓存中,单个读取结果可以在核心中的所有SIMD通道上广播等。为了实现这一点,内容无法改变的事实必须严格强制执行(使用内存别名,你现在可以绕过这个,但是如果你这样做,结果是非常不确定的)。如此统一实际上并不是要向其他程序员声明对const等软件工程优势的意图,而是宣告对编译器和驱动程序的意图,以便他们可以根据它进行优化。
D3D使用" const"和#34;恒定缓冲区"而不是统一,所以显然有一些重叠。虽然这确实会导致说出像#34;每帧更新常数多少次?"当你想到它是一种奇怪的事情说:)。这些值在着色器代码中是不变的,但在API级别上并非常常。
答案 1 :(得分:1)
这个词的词源在这里很重要。术语“均匀”源自GLSL,其灵感来自Renderman标准的着色器术语。 In Renderman,“uniform”用于“其值在表面的任何部分开始着色时保持不变”的值。这是“变化”的替代方法,它表示在表面上插值的值。
“常量”意味着值永远不会更改。统一值确实发生变化;它们根本不会以与其他值相同的频率变化。输入值每次调用都会更改,统一值会更改每次调用,并且常量值不会更改。请注意,在GLSL中,const
通常表示“编译时常量”:在编译时设置的值,永远不会更改。
Vulkan中的统一变量最终来自着色器外部的资源。由缓冲器提供的均匀变量块,由推动常量状态馈送的推动常数中的制服都是由用户设置的外部资源。这与编译时常量结构有着根本不同的概念。
由于它与常量结构不同,因此需要一个不同的术语来请求它。