简体   繁体   English

将 Vulkan memory 分配器与 Volk 一起使用

[英]Using Vulkan memory allocator with Volk

I'm currently trying to use Vulkan memory allocator with the meta loader Volk here is the link of the two: https://github.com/zeux/volk我目前正在尝试将 Vulkan memory 分配器与元加载器 Volk 一起使用,这是两者的链接: https://github.com/zeux/volk

https://gpuopen.com/vulkan-memory-allocator/ https://gpuopen.com/vulkan-memory-allocator/

But I have trouble with creating the VmaAllocator, here is my code:但是我在创建 VmaAllocator 时遇到了麻烦,这是我的代码:

void VulkApp::Init(PipelineFlags t_Conf, entt::registry& t_reg)
{
    volkInitialize();
    WindowProps props = {};
    props.Height = 600;
    props.Width = 800;
    props.Title = "Engine";
    currentWindow = EngWindow::Create(props);

    //Create all physical, logical, instance for vulkan
    Prepare();
    VolkDeviceTable test;
    volkLoadDeviceTable(&test, m_LogicalDevice->GetVkDevice());
    VmaAllocatorCreateInfo allocatorCreateInfo = {};
    allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
    allocatorCreateInfo.physicalDevice = m_PhysicalDevice->GetVkPhysicalDevice();
    allocatorCreateInfo.device = m_LogicalDevice->GetVkDevice();
    allocatorCreateInfo.instance = m_Instance->GetRawVkInstance();
    allocatorCreateInfo.pVulkanFunctions = reinterpret_cast<const VmaVulkanFunctions*> (&test);

    VmaAllocator allocator;
    vmaCreateAllocator(&allocatorCreateInfo, &allocator);
    BuildRenderPipelines(t_Conf, t_reg);
}

void VulkApp::Prepare()
{
    m_Instance = std::make_unique<VulkInst>();
    volkLoadInstance(m_Instance->GetRawVkInstance());
    currentWindow->CreateSurface(m_Instance->GetRawVkInstance(), &m_Surface);
    m_PhysicalDevice = std::make_unique<PhysicalDevice>(*m_Instance);
    m_LogicalDevice = std::make_unique<LogicalDevice>(*m_Instance, *m_PhysicalDevice, m_Surface);
    volkLoadDevice(m_LogicalDevice->GetVkDevice());
    m_SwapChain = std::make_unique<SwapChain>(ChooseSwapExtent(), *m_LogicalDevice, *m_PhysicalDevice, m_Surface);
    GraphicsHelpers::CreateCommandPool(m_CommandPool, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); //TODO: added Transient bit
    CreateFrameSyncResources();

    /*
    Create Camera
    */
    BuildSwapChainResources();
}

I don't have any error when i build, but when i execute, the VmaCreateAllocator return an error:我构建时没有任何错误,但是当我执行时,VmaCreateAllocator 返回错误:

Exception raised at 0x00007FFAB0CD836B (VkLayer_khronos_validation.dll) in My_Game.exe : 0xC0000005 : access violation reading location 0x0000000000000120.

Not very useful, but it stops on the line 14082 of the file vk_mem_alloc.h:不是很有用,但它停在文件 vk_mem_alloc.h 的第 14082 行:

(*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps);

The program check all the vulkan validation function so my vulkan function table must be good.该程序检查所有 vulkan 验证 function 所以我的 vulkan function 表必须是好的。 But still the allocation fail.但仍然分配失败。 I'm sorry i don't put a 'minimal' code, but with vulkan, even the minimum is really long.对不起,我没有放一个“最小”代码,但是对于 vulkan,即使是最小值也很长。 So, as a first test, maybe some of you have an insight of the error?所以,作为第一个测试,也许你们中的一些人对错误有洞察力?

If you use a loader like Volk, you need to provide all memory related Vulkan function pointers used by VMA yourself.如果你使用像 Volk 这样的加载器,你需要自己提供 VMA 使用的所有 memory 相关的 Vulkan function 指针。

This is done via the pVulkanFunctions member of the VmaAllocatorCreateInfo structure.这是通过VmaAllocatorCreateInfo结构的pVulkanFunctions成员完成的。

So when creating your VmaAllactor you set the function pointer in that to those fetched via Volk like this:因此,在创建VmaAllactor时,您将其中的 function 指针设置为通过 Volk 获取的指针,如下所示:

VmaVulkanFunctions vma_vulkan_func{};
vma_vulkan_func.vkAllocateMemory                    = vkAllocateMemory;
vma_vulkan_func.vkBindBufferMemory                  = vkBindBufferMemory;
vma_vulkan_func.vkBindImageMemory                   = vkBindImageMemory;
vma_vulkan_func.vkCreateBuffer                      = vkCreateBuffer;
vma_vulkan_func.vkCreateImage                       = vkCreateImage;
vma_vulkan_func.vkDestroyBuffer                     = vkDestroyBuffer;
vma_vulkan_func.vkDestroyImage                      = vkDestroyImage;
vma_vulkan_func.vkFlushMappedMemoryRanges           = vkFlushMappedMemoryRanges;
vma_vulkan_func.vkFreeMemory                        = vkFreeMemory;
vma_vulkan_func.vkGetBufferMemoryRequirements       = vkGetBufferMemoryRequirements;
vma_vulkan_func.vkGetImageMemoryRequirements        = vkGetImageMemoryRequirements;
vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
vma_vulkan_func.vkGetPhysicalDeviceProperties       = vkGetPhysicalDeviceProperties;
vma_vulkan_func.vkInvalidateMappedMemoryRanges      = vkInvalidateMappedMemoryRanges;
vma_vulkan_func.vkMapMemory                         = vkMapMemory;
vma_vulkan_func.vkUnmapMemory                       = vkUnmapMemory;
vma_vulkan_func.vkCmdCopyBuffer                     = vkCmdCopyBuffer;

And then pass those to the create info:然后将它们传递给创建信息:

VmaAllocatorCreateInfo allocator_info{};
...
allocator_info.pVulkanFunctions = &vma_vulkan_func;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM