vulkan中分配显存并拷贝数据的流程(vkBuffer、vkDeviceMemory的关系)以及VMA库介绍

在 Vulkan 中,VkBufferVkDeviceMemory 是两个不同的概念,但它们通常是一起绑定在一起用的

  1. VkBuffer 表示一个缓冲区对象。VkBuffer 本身只是逻辑上的概念,它不包含实际的数据存储,也不关心数据在内存中的具体位置。它是靠vkBindBufferMemory()函数绑定VkDeviceMemory,来关联具体显存资源的,也就是说,真正资源用VkDeviceMemory存储的

  2. VkDeviceMemory 设备内存对象(GPU显存),用于实际存储和管理 Vulkan 缓冲区对象的数据。一旦完成跟VkBuffer的绑定,它几乎就不太需要用到了,直接使用VkBuffer对象即可。但在后续资源销毁和释放的时候,需要调用vkDestroyBuffer()vkFreeMemory()分别销毁VkBuffer对象和vkDeviceMemory

一般的分配显存流程是:

  • 使用 vkCreateBuffer() 函数创建一个 VkBuffer 对象,定义了缓冲区的大小用途等属性。再次强调,它并不包含任何指向实际显存块的指针,只是一些信息

    VkBuffer vkBuffer; 
    VkBufferCreateInfo bufferCreateInfo= {}; 
    bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    bufferInfo.size = bufferSize;
    bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; 
    vkCreateBuffer(logicalDevice, &bufferCreateInfo, nullptr, &vkBuffer);
    
  • 使用 vkGetBufferMemoryRequirements() 函数从vkBuffer对象中获取缓冲区的内存需求信息,包括内存大小对齐要求等。

    VkMemoryRequirements memoryRequirements;
    vkGetBufferMemoryRequirements(logicalDevice, vkBuffer, &memoryRequirements);
    
  • 使用 vkAllocateMemory() 函数为缓冲区分配实际的设备内存(VkDeviceMemory),并将该内存与缓冲区关联起来。

    VkMemoryAllocateInfo allocateInfo = {};
    allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    allocateInfo.allocationSize = memoryRequirements.size;
    allocateInfo.memoryTypeIndex = findMemoryType(memoryRequirements.memoryTypeBits, properties);
    vkAllocateMemory(logicalDevice, &allocateInfo, nullptr, &vkDeviceMemory);
    
  • 最后,使用 vkBindBufferMemory() 函数将缓冲区对象和分配的设备内存关联起来,使得vkBuffer能够真的称为这块显存区域图像数据的handle。

    vkBindBufferMemory(device, vkBuffer, vkDeviceMemory, 0);
    

简化这个过程可以引入VMA(Vulkan Memory Allocator)
github地址:https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator

简单用法:

VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = 65536;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;

VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_AUTO;

VkBuffer buffer;
VmaAllocation allocation;
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr);

vmaCreateBuffer()函数调用实际做的工作为:

  • 创建 VkBuffer。
  • 根据需要分配 VkDeviceMemory 块。
  • 将内存块的未使用区域绑定到此缓冲区。

VmaAllocation是一个表示绑定到vkBuffer的已分配的内存。可以被用来获取 VkDeviceMemory 句柄和偏移量等参数。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宗浩多捞

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值