Экспорт дескриптора выделения памяти vulkan вызывает нехватку памяти устройства - PullRequest
2 голосов
/ 08 октября 2019

Я пытаюсь экспортировать дескриптор выделения памяти, сделанный Vulkan, чтобы импортировать его в OpenGL. Но когда я добавляю vk::ExportMemoryAllocateInfo в цепочку pNext vk::MemoryAllocateInfo, vk::Device::allocateMemory выдает исключение OutOfDeviceMemory.

Когда я не экспортирую дескриптор, распределение не происходит, но возвращенный дескриптор недействителен.

Вот код ошибки (пример на основе jherico: пример vulkan-opengl-interop-):

// 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);
}

Моя система:

  • Windows 7
  • Nvidia Quadro RTX 4000
  • Версия драйвера 431.02 или 431.94

Уровень проверки присутствует в моем экземпляре, но остается молчаливым, расширения VK_KHR_external_memory и VK_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и верните false с vk::ExternalMemoryHandleTypeFlagBits::eOpaqueWin32Kmt.

1 Ответ

0 голосов
/ 11 октября 2019

Я наконец-то получил vk :: ExternalMemoryHandleTypeFlagBits :: eOpaqueWin32Kmt. Мне не нужно взаимодействовать с ним через API Windows, просто OpenGL.

...