不正确的 Vulkan 统一缓冲区内存对齐
Incorrect Vulkan UniformBuffer Memory Alignment
根据规范,在统一缓冲区内声明的变量必须正确对齐。
我的结构中有以下 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::vec3
都可以通过简单地在glm::f32
和glm::uint32
上方声明它们来访问,但是,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)
,但没有组合工作。
统一缓冲区中的数组必须按照 std140 对齐,这基本上是 vec4 对齐的。
这意味着您的均匀缓冲区太小。至于着色器,浮点 foo[64] 实际上与 vec4 foo[64] 的大小相同。Alignas 限定符不允许您更改它。
要么使用存储缓冲区,这可能更慢,要么只在数组中使用 vec4。
相关文章:
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 在共享缓冲区内存中创建 ::std::string 对象
- OpenGL 调试上下文警告 -"将使用视频内存作为缓冲区异议的来源
- 如何从内存缓冲区加载张量流图
- 将 mmap 内存用于开销非常低的循环缓冲区
- 不正确的 Vulkan 统一缓冲区内存对齐
- 无锁环形缓冲区boost示例中的内存排序
- 为异步发送缓冲区保留内存(提升 asio 套接字)
- 来自iostream或内存缓冲区的Apache Arrow表
- 如何重复使用原始输入缓冲区内存?
- 如何释放协议缓冲区内存
- 如何正确复制内存缓冲区?
- 将不相邻的内存缓冲区视为连续缓冲区的数据结构
- 我可以在没有任何锁的情况下从不同的线程读取内存缓冲区吗?
- C++ - 读取进程内存到缓冲区,写入进程内存(同一缓冲区上的新值)将缓冲区恢复为旧值
- Vulkan中动态统一缓冲区的缓冲区内存分配
- 正确释放协议缓冲区内存
- 清除stdin缓冲区(内存占用空间)
- 线程写入缓冲区内存和线程内存