Vulkan 学习(5)---- Vulkan 内存分配

Overview

Vulkan 将内存管理的工作交给了开发者自己负责,如何分配内存,如何指定内存策略都是由开发者自己决定的,当然出了问题也是由开发者自己负责的

Vulkan 将内存划分为两大类:主机内存(Host Memory)设备内存(Device Memory)

在移动设备上,主机内存就是 CPU 内存,设备内存就是GPU 显存,在此基础上,每种内存类型还可以按照属性进一步划分
Vulkan 提供了一种透明的机制来显示内存的细节和相关属性,这样做在 opengl-es 中是完全不可能的,后者不允许应用程序显式的控制内存区域和布局
vulkan memory

Vulkan 中系统的内存有四种类型(并不是所有设备都支持这个四种类型):

  • Host Local Memory,只对 Host 可见的内存,通常称之为普通内存(可以理解为操作系统的内存)
  • Device Local Memory,只对 Device 可见的内存,通常称之为显存(可以理解为显卡上的显存)
  • Host Local Device Memory,由 Host 管理的,对 Device 可见的内存
  • Device Local Host Memory,由 Device 管理的,对 Host 可见的内存

对比这两种内存类型,主机内存(Host)比设备内存(Device)更慢,但是Host Memory 通常容量更大(也就是一般显存速度更快,但是容量更小)

设备内存,它对物理设备是直接可见的,物理设备可以直接读取其中的内存区块,设备内存和物理设备之间的关系十分紧密,因此它的性能比宿主机内存更高

VkImageVkBuffer,以及一致性的缓存对象Uniform Buffer都是从设备内存端分配的
单一的物理设备可能有多种类型的内存,根据它们的堆类型以及属性的不同还可能进一步细分

枚举内存信息

使用 vkGetPhysicalDeviceMemoryProperties 获取设备的内存信息,其函数定义如下:

VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
    VkPhysicalDevice                            physicalDevice,
    VkPhysicalDeviceMemoryProperties*           pMemoryProperties);

其中 physicalDevice 就是创建的物理设备,VkPhysicalDeviceMemoryProperties 定义如下:

typedef struct VkPhysicalDeviceMemoryProperties {
   
    // 内存类型数量和信息
    uint32_t        memoryTypeCount;
    VkMemoryType    memoryTypes[VK_MAX_MEMORY_TYPES];
    // 内存堆数量和信息
    uint32_t        memoryHeapCount;
    VkMemoryHeap    memoryHeaps[VK_MAX_MEMORY_HEAPS];
} VkPhysicalDeviceMemoryProperties;
  • memoryTypeCount 表示支持的内存类型数量
  • memoryTypes 有效元素个数为 memoryTypeCount 的内存类型信息数组
  • memoryHeapCount 表示支持的内存堆数量
  • memoryHeaps 有效元素是 memoryHeapCount 内存堆信息数组

其中 VkMemoryType 类型定义:

typedef struct VkMemoryType {
   
    VkMemoryPropertyFlags    propertyFlags;
    uint32_t                 heapIndex;
} VkMemoryType;
  • propertyFlags 内存类型标志位。
  • heapIndex 对应的 memoryHeaps 堆索引。

propertyFlags 有效值被定义在了 VkMemoryPropertyFlagBits 枚举中,其定义如下:

typedef enum VkMemoryPropertyFlagBits {
   
    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001,
    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002,
    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004,
    VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008,
    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010,
    VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020,
    VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040,
    VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080,
    VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100,
    VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkMemoryPropertyFlagBits;
typedef VkFlags VkMemoryPropertyFlags;
  • VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 表示该内存设备上分配的内存可以被物理设备高效访问,只有对应的堆为 VK_MEMORY_HEAP_DEVICE_LOCAL_BIT 才会有该内存类型(Device 内存)

  • VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 表示该内存设备上分配的内存将自动进行同步,不需要手动调用 vkFlushMappedMemoryRangesvkInvalidateMappedMemoryRanges 来进行内存同步

  • VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 表示在此内存类型上分配的内存可被 Host 端通过 vkMapMemory 函数进行映射,进而进行访问

  • VK_MEMORY_PROPERTY_HOST_CACHED_BIT 表示该内存类型上分配的内存为缓存类型,Host 端访问缓存的内存类型会比较快,但是非缓存内存总是同步内存(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)

  • VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT 表示在此内存类型上分配的内存只有物理设备可访问
    内存类型不能同时为 VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BITVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT

下图表示了 memory_type 和 相应的标志位之间的关系:
memory_type

另外的 VkMemoryHeap 的类型定义如下图所示:

typedef struct VkMemoryHeap 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值