Как правильно поделиться VkDeviceMemory? Для чего нужен VkExternalMemoryBufferCreateInfoKHR? - PullRequest
0 голосов
/ 25 апреля 2018

Это продолжение моего предыдущего поста. Короче говоря - у меня есть несколько VkDevice (и несколько все - свопчейны, буферы команд и т. Д.), И я хочу визуализировать одинаковую геометрию с этими ресурсами, т.е. Я не хочу загружать данные несколько раз. Как указал @Ekzuzy, я мог бы использовать VK_KHR_external_memory. Я пытался, и на самом деле это работает, но у меня остались некоторые вопросы, а также жалобы отладочного уровня.

Это самые важные шаги:

  1. Включите все необходимые расширения:

    instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
    instanceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME);
    instanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
    instanceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
    deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
    deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
    deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
    deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
    
  2. Создать локальную память устройства с данными. Он должен был быть общая память:

    a) create_staging_buffer_and_memory
    b) copy_data_to_staging_buffer
    c) create_device_local_buffer_and_memory
    d) copy_staging_buffer_to_device_local_buffer
    e) create_memory_handle
    

    VkBuffer объекты здесь временные и уничтожаются после Копирование закончено. Постановка памяти тоже. Создана локальная память устройства со структурой VkExportMemoryAllocateInfoKHR в VkMemoryAllocateInfo::pNext поле. Дескриптор памяти, полученный при вызове vkGetMemoryFdKHR. После этого шага у меня есть память с данными в устройстве и указателем на него.

  3. Создать VkBuffer и VkDeviceMemory, которые должны участвовать в реальном рендеринге. Память создана с VkImportMemoryFdInfoKHR структура в поле VkMemoryAllocateInfo::pNext, где я использую ручка, которую я получил раньше.

  4. Наконец, запишите буфер команд, в котором привязать буфер с шага 3.

Как я уже писал ранее - я вижу вывод, но слой отладки говорит мне:

layer MEM: vkCmdBindVertexBuffers (): невозможно прочитать недопустимую область Выделение памяти 0x17 для связанного объекта Buffer 0x16, пожалуйста, заполните памяти перед использованием.

Я не уверен почему. И как слой знает, что память недействительна. В любом случае это выглядит неправильно для меня, и я не должен беспокоиться об этом предупреждении. Или должен?

Другой вопрос касается VkExternalMemoryBufferCreateInfoKHR, который используется в VkBufferCreateInfo::pNext. Документация не ясна для меня, что она делает - вся информация, которую она имеет, является типом некоторой ручки. Какая ручка? И приложение работает так же с и без указанной структуры.

Обновление: похоже, что предупреждение о слое ошибка .

1 Ответ

0 голосов
/ 25 апреля 2018

VkExternalMemoryBufferCreateInfoKHR предназначен для создания памяти, которая используется совместно с API или, возможно, между экземплярами или устройствами Vulkan , где базовое физическое устройство одинаково .

В моем репозитории примеров здесь есть пример использования API внешней памяти для обмена информацией об изображениях текстуры между OpenGL и Vulkan. В этом примере используются версии API Win32 HANDLE, но функциональность эквивалентна версиям FD, просто с другим типом для хранения идентификатора, который будет передаваться между различными API.

Другой вопрос касается VkExternalMemoryBufferCreateInfoKHR, который используется в VkBufferCreateInfo :: pNext

Эта структура используется для информирования экземпляра vulkan о том, что рассматриваемый буфер может использоваться совместно, что может повлиять на то, как драйвер Vulkan управляет им внутренне.

I думаю эта структура используется при создании буфера Vulkan из внешней памяти. Во время создания буфера (или изображения) вы должны использовать эту структуру, чтобы отметить, что изображение будет поддерживаться внешней памятью, а затем вместо обычного выделения вы установите pNext для MemoryAllocateInfo в экземпляр ImportMemoryHostPointerInfoEXT, содержащий общая ручка. Я подозреваю, что это не используется в моем примере, потому что там я использую Vulkan только для экспорта, а сторона GL выполняет импорт. Если вы используете Vulkan как для экспорта, так и для импорта, он может вам понадобиться.

...