导出 vulkan 内存分配句柄导致设备内存不足

Exporting vulkan memory allocation handle cause an out of device memory

我正在尝试导出 Vulkan 进行的内存分配句柄,以将其导入 OpenGL。但是当我在 vk::MemoryAllocateInfopNext 链中添加 vk::ExportMemoryAllocateInfo 时,vk::Device::allocateMemory 会抛出 OutOfDeviceMemory 异常。

当我不导出句柄时,分配不会失败但 returned 句柄无效。

这里是错误代码(基于 jherico 的例子:vulkan-opengl-interop-example):

// The physical device and the device are correct
// requirements are for a RGBA image of 1024x1024 pixels
// memory properties is just vk::MemoryPropertyFlagBits::eDeviceLocal
void IMemoryObject::Allocate(vk::PhysicalDevice physicalDevice, vk::Device device, const vk::MemoryRequirements& requirements, vk::MemoryPropertyFlags properties)
{
        unsigned int memoryTypeIndex = 0;
        bool memoryIndexTypeFound = false;
        vk::PhysicalDeviceMemoryProperties memoryProperties = physicalDevice.getMemoryProperties();

        for (unsigned int i = 0; i < memoryProperties.memoryTypeCount && !memoryIndexTypeFound; i++)
        {
            vk::MemoryType memoryType = memoryProperties.memoryTypes[i];
            if (requirements.memoryTypeBits & 1 << i && (memoryType.propertyFlags & properties) == properties)
            {
                memoryTypeIndex = i;
                memoryIndexTypeFound = true;
            }
        }

        if (!memoryIndexTypeFound)
            throw std::exception();

        vk::ExportMemoryAllocateInfo exportAllocInfo;
        exportAllocInfo.setHandleTypes(vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32);

        vk::MemoryAllocateInfo allocateInfo;
        allocateInfo.setPNext(&exportAllocInfo); // Remove this line and the allocation won't fail
        allocateInfo.setAllocationSize(requirements.size);
        allocateInfo.setMemoryTypeIndex(memoryTypeIndex);

        deviceMemory_ = device.allocateMemoryUnique(allocateInfo);

        // Call VkBindBufferMemory or VkBindImageMemory, never reached anyway when allocateInfo.pNext == &exportAllocInfo;
        BindMemory(*deviceMemory_, 0);
}

我的系统是:

验证层存在于我的实例中但保持沉默,扩展 VK_KHR_external_memoryVK_KHR_external_memory_win32 在我的设备中可用,分配大小遵守 API 限制并且 memoryIndexType 是正确。

我是做错了什么还是我错过了限制?

谢谢!

编辑:

我尝试将句柄导出为 vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt 并且分配有效。下面的代码是我如何测试分配是否需要专用分配来导出句柄类型。

bool RequireDedicatedAllocation(vk::PhysicalDevice physicalDevice, const vk::ImageCreateInfo& createInfo, vk::ExternalMemoryHandleTypeFlagBits handleType)
{
    vk::PhysicalDeviceExternalImageFormatInfo externalImageFormatInfo;
    externalImageFormatInfo.setHandleType(handleType);

    vk::PhysicalDeviceImageFormatInfo2 imageFormatInfo;
    imageFormatInfo.setUsage(createInfo.usage)
                   .setFormat(createInfo.format)
                   .setTiling(createInfo.tiling)
                   .setType(createInfo.imageType)
                   .setPNext(&externalImageFormatInfo);

    vk::StructureChain<vk::ImageFormatProperties2, vk::ExternalImageFormatProperties> imageFormatPropertiesChain = physicalDevice.getImageFormatProperties2<vk::ImageFormatProperties2, vk::ExternalImageFormatProperties>(imageFormatInfo);
    vk::ExternalImageFormatProperties externalImageProperties = imageFormatPropertiesChain.get<vk::ExternalImageFormatProperties>();

    return static_cast<bool>(externalImageProperties.externalMemoryProperties.externalMemoryFeatures & vk::ExternalMemoryFeatureFlagBits::eDedicatedOnly);
}

在我的系统上,它抛出一个 ErrorFormatNotSupported 错误(在 vk::PhysicalDevice::getImageFormatProperties2 上)vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32 和 return false vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt

我终于得到了 vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt。我不需要通过 Windows' API 与它交互,只需 OpenGL。