16

我想弄清楚,但我有点卡住了。

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

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

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

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

4

1 回答 1

21

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有一个索引指向分配它的内存的堆。


我唯一没有得到的是这两个DEVICE_LOCAL标志是如何相互作用的。

你看规范了吗?它并没有完全隐藏它是如何工作的:

如果设置propertyFlags了该VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT位,则分配给这种类型的内存对于设备访问是最有效的。此属性只会为属于具有该集合的堆的内存类型VK_MEMORY_HEAP_DEVICE_LOCAL_BIT设置。

是说如果内存是本地的,那么与该内存对应的所有类型都是本地的,还是说它们可以是本地的?

您似乎试图对这些事情施加错误的含义。只需看一下规范所说的内容,并从表面上看。

PROPERTY_DEVICE_LOCAL表示将实现最佳设备访问性能的内存类型。这和之间的唯一联系MEMORY_DEVICE_LOCAL是,内存类型PROPERTY_DEVICE_LOCAL仅与使用 的内存堆相关联MEMORY_DEVICE_LOCAL

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

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

但是,以使其主机可见的方式从该池分配内存可能会降低设备访问该内存的性能。因此,对于这样的硬件,同一堆的主机可见内存类型将不会使用PROPERTY_DEVICE_LOCAL

再说一次,其他硬件不会因为使内存主机可见而失去性能。所以它们只有一种内存类型,它具有所有可用属性。对于英特尔来说,他们的片上 GPU 显然可以访问某种级别的 CPU 缓存。

于 2016-04-05T21:04:38.187 回答