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

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

  1. VkBuffer 表示一个缓冲区对象,用于存储数据,比如顶点数据、索引数据等。VkBuffer 本身只是逻辑上的概念,它不包含实际的数据存储,也不关心数据在内存中的具体位置

  2. VkDeviceMemory 设备内存对象(GPU显存),用于实际存储 Vulkan 缓冲区对象的数据。缓冲区需要分配显存后才能存储实际的数据,最后成功分配的显存块是通过 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能够真正使用这块显存。

    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 句柄和偏移量等参数。

你可能感兴趣的:(Vulkan,c++)