Vulkan 内存对齐要求

Vulkan memory alignment requirements

本文关键字:对齐 内存 Vulkan      更新时间:2023-10-16

我正在为 Vulkan 设备内存实现一个朴素的内存管理器,并希望确保我了解内存的对齐要求以及如何满足它们。

因此,假设我已经使用 vkAllocateMemory 分配了一个内存"池",并希望将此池中的内存块子分配给各个资源(基于 VkMemoryRequirements 结构(,以下伪代码是否能够分配具有正确大小和对齐要求的内存部分?

  • 请求具有所需大小和所需对齐的内存
  • 遍历池中的块,寻找一个空闲且大小> RequiredSize 的块
  • 如果当前块在内存中的偏移量不能被 RequiredAlignment 整除,请找出对齐和余数之间的差异
  • 如果当前块的大小减去差值小于 RequiredSize,请跳到池中的下一个块
  • 如果差值
  • 大于 0,则插入大小等于差值的填充块,并调整当前未分配的块大小和偏移量
  • 从当前未分配块(现已对齐(的开头分配 RequiredSize 字节,相应地调整未分配块的大小和偏移
  • 返回 vkDeviceMemory 句柄(池(、大小和偏移量(新分配的块(
  • 如果我们到达阻止列表的末尾,则此池无法分配内存

换句话说,我们只需要确保偏移量是必需对齐的倍数吗?

换句话说,我们只需要确保偏移量是必需对齐的倍数吗?

对于对齐,这几乎就足够了。

在 vkBindbufferMemory 中,有效的使用要求之一是:

memoryOffset必须是调用vkGetBufferMemoryRequirementswithbuffer返回的VkMemoryRequirements结构的alignment成员的整数倍

并且在 vkBindImageMemory 的有效使用要求中有一个并行语句:

memoryOffset必须是调用vkGetImageMemoryRequirementswithimage返回的VkMemoryRequirements结构的alignment成员的整数倍

如果前一个块包含非线性资源,而当前块是线性的,反之亦然,则对齐要求是 VkMemoryRequirements.align 和设备的 bufferImageGranularity 的最大值。这还需要检查内存块的末端。

但是,您还需要考虑到必须在VkMemoryRequirementsmemoryTypeBits标志中设置池的内存类型。