Vulkan 内存

内存分类

Vulkan 的内存分为两类: 宿主机内存设备内存

两种内存的特点:

  • 宿主机内存   访问速度慢 ,但可分配空间大。
  • 设备内存     直接对设备可见的,可分配空间小,但访问速度快。

宿主机内存

Vulkan 通过宿主机内存来存储API 的内部数据结构, Vulkan 允许程序控制宿主机端的内存分配,宿主机的内存管理通过以下数据结构来完成:

typedef struct VkAllocationCallbacks {
    Void*                                 pUserData;
    PFN_vkAllocationFunction              pfnAllocation;
    PFN_vkReallocationFunction            pfnReallocation;
    PFN_vkFreeFunction                    pfnFree;
    PFN_vkInternalAllocationNotification  pfnInternalAlloc;
    PFN_vkInternalFreeNotification        pfnInternalFree;
} VkAllocationCallbacks ;

设备内存

设备内存, 即GPU 内存,它对于物理设备是直接可见的, 物理设备可以直接读取其中的内存区块。图像对象缓存对象,以及一致变量的缓存对象都是在设备内存端分配的。

单一设备可能有多种内存类型,根据堆类型以及属性的不同还可以进一步细分。

查询内存堆和属性的函数:

void vkGetPhysicalDeviceMemoryProperties(
    VkPhysicalDevice                       physicalDevice,
    VkPhysicalDeviceMemoryProperties*      pMemoryProperties
); 

typedef struct VkPhysicalDeviceMemoryProperties { 
    Uint32_t         memoryTypeCount;
    VkMemoryType     memoryTypes[VK_MAX_MEMORY_TYPES];
    Uint32_t         memoryHeapCount;
    VkMemoryHeap     memoryHeaps[VK_MAX_MEMORY_HEAPS];
} VkPhysicalDeviceMemoryProperties;
  • 内存类型
typedef struct VkMomoryType {
	VkMemoryPropteryFlags propertyFlags;              // 属性
    uint32_t              heapIndex;                  // 堆索引号
} VkMemoryType;

注意 HOST_COHERENT_BIT , HOST_CACHED_BIT 和  LAZILY_ALLOCATED_BIT 的用法。

LAZILY_ALLOCATED_BIT 只能被设备端访问,与HOST_PROPERTY_HOST_VISIBLE_BIT 和 HOST_COHERENT_BIT 条件排斥。

  • 内存堆
typedef struct VkMemoryHeap {
	VkDeviceSize          size;                 //堆的大小
    VkMemoryHeapFlags     flags;                //堆的属性
} VkMemoryHeap;

typedef enum VkMemoryHeapFlagBits {
    VK_MEMORY_HEAP_DEVICE_LOCAL_BIT       = 0x00000001,
    VK_MEMORY_HEAP_MULTI_INSTANCE_BIT     = 0x00000002,
    VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT,
    VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM     = 0x7FFFFFFF
} VkMemoryHeapFlagBits;

 分配内存

VkResult vkAllocateMemory (
    VkDevice                       device;
    const VkMemoryAllocateInfo*    allocateInfo,
    const VkAllocationCallbacks*   allocator,
    VkDeviceMemory*                memory
);
typedef struct VkMemoryAllocateInfo {
	VkStructureType  type;
    Const void*      pNext;
    VkDeviceSize     allocationSize;
    uint32_t         momoryTypeIndex;        // 内存类型索引
} VkMemoryAllocateInfo;

 注意 物理设备内存端的可分配对象的数量是有限的,可以通过 VkPhysicalDeviceLimits 成员的   maxMemoryAllocationCount  查询 (4096 )。

释放内存

Void VkFreeMemory (
	VkDevice          device,
    VkDeviceMemory    memory,
    const VkAllocationCallbacks* allocator
);

从宿主机访问设备内存

宿主机只能访问那些支持映射的内存类型 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,通过 vkMapMemory() 来实现宿主机对设备内存的映射访问。

VkResult  vkMapMemory (
	VkDevice           device;
    VkDeviceMemory     memory,
    VkDeviceSize       offset,
    VkDeviceSize       size,
    VkMemoryMapFlags   flags,
    Void**             ppData
);

注意 :函数 VkMapMemory 不会检查内存区域是否被映射过,应用程序需要管理映射内存对象,访问已经映射的内存可能会导致无法预测的行为,甚至导致驱动程序死机。

当更新完内容后,通过结束映射使设备修改的内容反射回设备端。

当更新完内容后,通过结束映射使设备修改的内容反射回设备端。
Void vkUnMapMemory( VkDevice device, VkDeviceMemory memory);

映射过的内存需不需要再次映射? 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值