Ошибка vkCreateDevice от Vulkan: ошибка VK_ERROR_EXTENSION_NOT_PRESENT

#vulkan

#vulkan

Вопрос:

Я начинаю с Vulkan и следую руководству Нико Кауппи на Youtube.

У меня ошибка при создании устройства с помощью vkCreateDevice, она возвращает VK_ERROR_EXTENSION_NOT_PRESENT

Вот некоторая часть моего кода:

  1. Вызов vkCreateDevice

     _gpu_count = 0;
    vkEnumeratePhysicalDevices(instance, amp;_gpu_count, nullptr);
    std::vector<VkPhysicalDevice> gpu_list(_gpu_count);
    vkEnumeratePhysicalDevices(instance, amp;_gpu_count, gpu_list.data());
    _gpu = gpu_list[0];
    
    vkGetPhysicalDeviceProperties(_gpu, amp;_gpu_properties);
    
    VkDeviceCreateInfo device_create_info = _CreateDeviceInfo();
    
    vulkanCheckError(vkCreateDevice(_gpu, amp;device_create_info, nullptr, amp;_device));
      

_gpu_count = 1 и _gpu_properties, похоже, хорошо распознают мой графический процессор nvidia (который не обновлен)

  1. device_create_info

     VkDeviceCreateInfo _createDeviceInfo;
    
    _createDeviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    _createDeviceInfo.queueCreateInfoCount = 1;
    VkDeviceQueueCreateInfo _queueInfo = _CreateDeviceQueueInfo();
    _createDeviceInfo.pQueueCreateInfos = amp;_queueInfo;
      

Я не понимаю значения ошибки: «Запрошенное расширение не поддерживается» в соответствии с документом Хроноса.

Спасибо за вашу помощь

Комментарии:

1. устанавливаете ли вы enabledExtensionCount и / или ppEnabledExtensionNames члены _createDeviceInfo ? вот где помещаются запрошенные расширения

2. @ratchetfreak нет, все, что я делаю с _createDeviceInfo, находится во второй цитате кода

Ответ №1:

VK_ERROR_EXTENSION_NOT_PRESENT возвращается, когда одно из расширений в [ enabledExtensionCount , ppEnabledExtensionNames ] vector, которое вы указали, не поддерживается драйвером (как запрошено vkEnumerateDeviceExtensionProperties() ).

Расширения также могут иметь зависимости, поэтому VK_ERROR_EXTENSION_NOT_PRESENT также возвращается, когда зависимость расширения от расширения в списке также отсутствует.

Если вам не нужны расширения устройства, убедитесь enabledExtensionCount VkDeviceCreateInfo , что это 0 (а не, например, какое-то неинициализированное значение).

Я предполагаю, что 2. это все тело _CreateDeviceInfo() , которое подтвердит подозрение на «неинициализированное значение».

Обычно, хотя вы хотели бы, чтобы расширение swapchain могло отображаться на экране напрямую.

Комментарии:

1. Здравствуйте, я попытался добавить ppEnabledExtensionsNames, и я получаю другую ошибку, я не знаю, имеет ли проблема то же происхождение или нет. Это исключение 0xC0000005 Нарушение доступа, в Debug, как и в Realease, оно находится в 0x0000000069C492D8 (nvoglv64.dll ) в 0x0000000000000014 это происходит в vkCreateDevice. Спасибо

2. [ enabledExtensionCount , ppEnabledExtensionNames ] — вектор бедняка. Укажите также соответствующее enabledExtensionCount , иначе вы можете заставить команду Vulkan считывать за пределы.

Ответ №2:

Прежде всего, убедитесь, что ваш VkDeviceCreateInfo номер заполнен нулем, иначе он может привести к мусору в вашем VkCreateDevice() вызове.

Добавьте следующую строку сразу после объявления вашего VkDeviceCreateInfo:

 memset ( amp;_createDeviceInfo, 0, sizeof(VkDeviceCreateInfo)  );
  

Некоторые расширения абсолютно необходимы, например, swapchain.

Чтобы получить доступные расширения, выполните следующие действия:

 // Available extensions and layers names
const char* const* _ppExtensionNames = NULL;    
// get extension names
uint32 _extensionCount = 0;
vkEnumerateDeviceExtensionProperties( _gpu, NULL, amp;_extensionCount, NULL);
std::vector<const char *> extNames;
std::vector<VkExtensionProperties> extProps(_extensionCount);
vkEnumerateDeviceExtensionProperties(_gpu, NULL, amp;_extensionCount, extProps.data());
for (uint32_t i = 0; i < _extensionCount; i  ) {
    extNames.push_back(extProps[i].extensionName);
}
 _ppExtensionNames = extNames.data();
  

Как только у вас появятся все имена расширений _ppExtensionNames , передайте их в свою структуру deviceCreateInfo:

  VkDeviceCreateInfo  device_create_info ...
    [...]
    device_create_info.enabledExtensionCount = _extensionCount;
    device_create_info.ppEnabledExtensionNames = _ppExtensionNames;
    [...]
vulkanCheckError(vkCreateDevice(_gpu, amp;device_create_info, nullptr, amp;_device));
  

Надеюсь, это поможет.
Пожалуйста, дважды проверьте приведенный выше код, так как я пишу его наизусть.

Комментарии:

1. И, пожалуйста, не делайте этого в рабочей среде. Вы должны активировать только те расширения, которые вам действительно нужны, и никогда не активируйте расширения вслепую только потому, что они доступны на платформе. Расширения могут сильно замедлить работу программы, но вы ничего не получите обратно, если ваш код активно их не использует. Таким образом, правильный способ — сохранить списки обязательных и необязательных расширений для вашего приложения, проверить их vkEnumerateDeviceExtensionProperties и отреагировать соответствующим образом.