有人可以帮助我了解 VkPhysicalDeviceMemoryProperties 吗?

Could someone help me understand VkPhysicalDeviceMemoryProperties?

我正在努力弄清楚,但我有点卡住了。

类型和堆的关联方式很简单,虽然有点奇怪。 (为什么不给 VkMemoryHeap 一个 VkMemoryType 会员?)

我想我理解所有 VkMemoryPropertyFlags 的意思,它们看起来相当简单。

但是 VkMemoryHeap.flags 成员怎么了?它显然只有一个非零有效值,VkMemoryHeapFlagBits.VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,虽然它本身并不太奇怪,但还有一个 VkMemoryPropertyFlagBits.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 可能存在于堆的内存类型中.

VkMemoryHeap.flags 成员是什么意思,它与 VkMemoryType.flags 成员有什么关系?

Vulkan 在内存方面识别两个不同的概念。有设备可以与之通信的实际物理 RAM 块。然后有 方法 从这些 RAM 池之一分配内存。

堆代表一块特定的RAM。 VkMemoryHeap 是描述设备可以与之通信的可用 RAM 堆之一的对象。确实没有那么多东西可以定义一个特定的堆。只有两个:RAM 存储的字节数和存储相对于 Vulkan 设备的位置(本地与非本地)。

内存类型是从特定堆分配内存的特定方式VkMemoryType 是描述分配内存的特定方式的对象。还有很多关于如何从堆中分配内存的描述性标志。

有关更具体的示例,请考虑具有独立 GPU 的标准 PC 设置。该设备有自己的本地 RAM,但独立的 GPU 也可以访问 CPU 内存。所以一个 Vulkan 设备将有两个堆:一个是本地的,另一个是非本地的。

不过,通常会有两种以上的内存类型。您通常有一种表示本地内存的内存类型,它没有 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 集。这意味着您无法映射内存;您只能通过来自其他内存类型(或渲染操作或其他)的传输操作访问它。

但是您通常会有两种内存类型,它们都使用相同的非本地堆。它们都是 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,因此允许映射。但是,其中一个可能会设置 VK_MEMORY_PROPERTY_HOST_CACHED_BIT 标志,而另一个将设置 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT。这允许您选择是否要缓存 CPU 访问(因此需要显式刷新修改内存的范围)或未缓存 CPU 访问。

但是虽然它们是两种不同的内存类型,但它们都从同一个 分配。这就是为什么 VkMemoryType 有一个索引指向从中分配内存的堆。


Only thing I'm not getting is how the two DEVICE_LOCAL flags interact.

你看过说明书了吗?它并没有完全隐藏它是如何工作的:

if propertyFlags has the VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set, memory allocated with this type is the most efficient for device access. This property will only be set for memory types belonging to heaps with the VK_MEMORY_HEAP_DEVICE_LOCAL_BIT set.

Is it saying that if the memory is local then all types corresponding to that memory are local, or that they can be local?

你似乎试图将错误的含义强加给这些东西。看看说明书上写的就知道了。

PROPERTY_DEVICE_LOCAL表示能达到最佳设备访问性能的内存类型。这与 MEMORY_DEVICE_LOCAL 之间的唯一联系是具有 PROPERTY_DEVICE_LOCAL 的内存类型将仅与使用 MEMORY_DEVICE_LOCAL.

的内存堆相关联

这是这里唯一相关的含义。

如果您想要一个内存堆何时是设备本地但内存类型不是本地设备的示例,请考虑一个没有自己内存的 GPU。只有一个堆,因此是 MEMORY_DEVICE_LOCAL.

但是,以主机可见的方式从该池分配内存可能会降低设备访问该内存的性能。因此,for such hardware,同一个堆的主机可见内存类型不会使用PROPERTY_DEVICE_LOCAL

此外,other hardware 不会因内存主机可见而损失性能。所以他们只有一种内存类型,它具有所有可用的属性。对于英特尔,他们的片上 GPU 显然可以访问某些级别的 CPU 缓存。