不正确的Vulkan UniformBuffer内存对齐

时间:2019-11-28 11:46:26

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

Pug website在统一缓冲区内声明的变量必须正确对齐。

我的结构中包含以下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::vec3glm::f32以上即可访问glm::uint32,而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{};
};
    移动之后,即可访问
  • positionambientdiffuse 它们放在结构的顶部。

我已经设置了#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES,但是它似乎不适用于glm::f32glm::uint32以及其他人。 我需要怎么做才能使这些变量在统一缓冲区中工作?我尝试将alignas(4)alignas(8)alignas(16)和{{1 }},但不能合并使用。

1 个答案:

答案 0 :(得分:0)

统一缓冲区中的数组必须按照std140进行对齐,该标准基本上规定了vec4对齐。

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

要么使用存储缓冲区(可能会更慢),要么仅使用vec4在数组中。