Vulkan UniformBuffer 内存对齐不正确 [重复]
Posted
技术标签:
【中文标题】Vulkan UniformBuffer 内存对齐不正确 [重复]【英文标题】:Incorrect Vulkan UniformBuffer Memory Alignment [duplicate] 【发布时间】:2019-11-28 11:46:26 【问题描述】:As per the specification 在统一缓冲区中声明的变量必须正确对齐。
我的结构中有以下 GLM 变量:
struct UniformBufferObject_PointLights
glm::f32 constant[64];
glm::f32 linear[64];
glm::f32 quadratic[64];
glm::vec3 position[64];
glm::vec3 ambient[64];
glm::vec3 diffuse[64];
glm::int32 count;
;
尝试从着色器行为中访问任何变量
好像它们的值都是 0。问题集中在
glm::f32
和 glm::uint32
声明。
只需在glm::f32
和glm::uint32
上方声明即可访问glm::vec3
,但是glm::uint32
和glm::f32
仍然无法访问。 在这一点上,我认为这一定是对齐问题。
// After rearrangement.
struct UniformBufferObject_PointLights
glm::vec3 position[64];
glm::vec3 ambient[64];
glm::vec3 diffuse[64];
glm::f32 constant[64];
glm::f32 linear[64];
glm::f32 quadratic[64];
glm::uint32 count;
;
position
,ambient
,diffuse
移动后都可以访问
它们位于结构的顶部。
我已经设置了#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
,但它似乎不适用于glm::f32
和glm::uint32
,可能还有其他人。 我需要做些什么才能让这些变量在我的统一缓冲区中工作?我尝试将 alignas(4)
、alignas(8)
、alignas(16)
和 alignas(32)
放在它们的声明之前,但没有组合有效。
【问题讨论】:
【参考方案1】:统一缓冲区中的数组必须按照 std140 对齐,这基本上说明了 vec4 对齐。
这意味着您的统一缓冲区太小。至于着色器,float foo[64] 实际上与 vec4 foo[64] 的大小相同。 alignas 限定符不允许您更改它。
要么使用存储缓冲区,这可能会更慢,要么只使用数组中的 vec4。
【讨论】:
SSBO 无济于事;vec3
s 始终是 16 字节对齐的,即使在 std430 布局中也是如此。
确实如此。但是标量是紧密排列的。 Vec3 几乎从未紧密封装在任何 API 中。将它们提升到 vec4 的开销也比使用标量要小得多。编辑:这个问题的结束并不是那么好,因为它不仅仅是关于 vec3,而且标量数组是 vec4,假设的重复没有解决。以上是关于Vulkan UniformBuffer 内存对齐不正确 [重复]的主要内容,如果未能解决你的问题,请参考以下文章