【问题标题】:Incorrect Vulkan UniformBuffer Memory Alignment [duplicate]Vulkan UniformBuffer 内存对齐不正确 [重复]
【发布时间】: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::f32glm::uint32 声明。

只需在glm::f32glm::uint32 上方声明即可访问glm::vec3,但是glm::uint32glm::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::f32glm::uint32,可能还有其他人。 我需要做些什么才能让这些变量在我的统一缓冲区中工作?我尝试将 alignas(4)alignas(8)alignas(16)alignas(32) 放在它们的声明之前,但没有组合有效。

【问题讨论】:

    标签: c++ vulkan memory-alignment glm-math


    【解决方案1】:

    统一缓冲区中的数组必须按照 std140 对齐,这基本上说明了 vec4 对齐。

    这意味着您的统一缓冲区太小。至于着色器,float foo[64] 实际上与 vec4 foo[64] 的大小相同。 alignas 限定符不允许您更改它。

    要么使用存储缓冲区,这可能会更慢,要么只使用数组中的 vec4。

    【讨论】:

    • SSBO 无济于事; vec3s 始终是 16 字节对齐的,即使在 std430 布局中也是如此。
    • 确实如此。但是标量是紧密排列的。 Vec3 几乎从未紧密封装在任何 API 中。将它们提升到 vec4 的开销也比使用标量要小得多。编辑:这个问题的结束并不是那么好,因为它不仅仅是关于 vec3,而且标量数组是 vec4,假设的重复没有解决。
    猜你喜欢
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 2018-07-21
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    相关资源
    最近更新 更多