有人可以帮我理解VkPhysicalDeviceMemoryProperties吗?

Alp*_*der 12 memory-management vulkan

我想弄清楚,但我有点陷入困境.

类型和堆相关的方式很简单,如果有点奇怪.(为什么不给VkMemoryHeap一个VkMemoryType会员?)

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

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

VkMemoryHeap.flags会员意味着什么以及它与VkMemoryType.flags会员有什么关系?

Nic*_*las 16

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缓存.