Используя vkEnumerateInstanceVersion, чтобы получить точную версию Vulkan API

Я использую vkEnumerateInstanceVersion, чтобы получить версию vulkan API и передать ее в структуру VkApplicationInfo. Я легко различаю VK_VERSION_1_0 и VK_VERSION_1_1

//query the api version in order to use the correct vulkan functionality
PFN_vkEnumerateInstanceVersion FN_vkEnumerateInstanceVersion = 
PFN_vkEnumerateInstanceVersion(vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"));
uint32_t *instanceVersion = (uint32_t*)malloc(sizeof(uint32_t));
VkResult result = FN_vkEnumerateInstanceVersion(instanceVersion);

//check what is returned
if (result == VK_SUCCESS){
    std::cout<<"RESULT(vkEnumerateInstanceVersion) : Intance version enumeration successful"<<std::endl;
    if (instanceVersion!=nullptr){
        std::cout<<"API_VERSION : VK_API_VERSION_1_1"<<std::endl;
        appInfo.apiVersion = VK_API_VERSION_1_1;
    }
    else{
        std::cout<<"API_VERSION : VK_API_VERSION_1_0"<<std::endl;
    }
    std::cout<<"Version number returned : "<<*instanceVersion<<std::endl;
}else if (result == VK_ERROR_OUT_OF_HOST_MEMORY){
    std::cerr<<"RESULT(vkEnumerateInstanceVersion) : VK_ERROR_HOST_OUT_OF_MEMORY"<<std::endl;
}else{
    std::cerr<<"RESULT(vkEnumerateInstanceVersion) : Something else returned while enumerating instance version"<<std::endl;
}

Я использую приведенный выше код, чтобы получить версию API. В спецификации вулкана указано:

Чтобы запросить версию функциональности уровня экземпляра, поддерживаемую реализация, звоните: // Предоставлено VK_VERSION_1_1 VkResult vkEnumerateInstanceVersion( uint32_t* pApiVersion);

Комментарий в блоке выше означает, что это предоставлено VK_VERSION_1_1, а не VK_VERSION_1_0. Теперь, когда я открываю терминал и набираю:

vulkaninfo | head -n 5

Я получаю следующее:

ERROR: [Loader Message] Code 0 : /usr/lib32/libvulkan_intel.so: wrong ELF class: ELFCLASS32
ERROR: [Loader Message] Code 0 : /usr/lib32/libvulkan_radeon.so: wrong ELF class: ELFCLASS32
==========
VULKANINFO
==========

Vulkan Instance Version: 1.2.159

Это означает, что у меня есть VK_API_VERSION_1_2. Я хочу получить точную версию API. При выполнении первого блока кода я получаю:

RESULT(vkEnumerateInstanceVersion) : Intance version enumeration successful
API_VERSION : VK_API_VERSION_1_1
Version number returned : 4202655

Есть ли способ определить VK_VERSION_1_1 или VK_VERSION_1_2 в программе. Также я проверяю справочник vulkan для версии 1.2.165

Почему вы выделяете целое число в куче, а не просто заполняете переменную стека?

Nicol Bolas 20.12.2020 17:45

Переход только от instanceVersion к FN_vkEnumerateInstanceVersion дает ошибку

brightprogrammer 20.12.2020 17:46

Я попробовал это первым: uint32_t *instanceVersion; FN_vkEnumerateInstanceVersion(instanceVersion);

brightprogrammer 20.12.2020 17:48

Я не говорил создавать переменную стека, которая является указателем на целое число. Я сказал создать переменную стека, которая является целым числом; затем вы передаете указатель на эту переменную Vulkan. Я надеюсь, что вы не используете кучу других вещей где-то еще в своем коде Vulkan.

Nicol Bolas 20.12.2020 17:48

Хорошо, позвольте мне попробовать это... Нет, я этого не делаю... пока что в моем файле cpp присутствует только 116 строк кода.

brightprogrammer 20.12.2020 17:55
uint32_t instanceVersion, *pInstanceVersion; pInstanceVersion = &instanceVersion; ?
brightprogrammer 20.12.2020 17:57

А потом FN_vkEnumerateInstanceVersion(pInstanceVersion);

brightprogrammer 20.12.2020 17:58

Я не понимаю, в чем проблема. Версия экземпляра возвращается из файла vkEnumerateInstanceVersion. Вот и все. Что вы имеете в виду под "точной версией API". Насколько точнее вы хотите этого, чем то, что дает вам команда?

krOoze 20.12.2020 18:04

@krOoze Возвращает число. Как я узнаю, что это 1.1 или 1.2 во время выполнения?

brightprogrammer 20.12.2020 18:06

krOoze 20.12.2020 19:41

Ладно, никогда не знал, что такой макрос существует... Спасибо... @krOoze. Это имеет больше смысла.

brightprogrammer 20.12.2020 23:11
Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
11
2 383
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
Я использую vkEnumerateInstanceVersion, чтобы получить версию vulkan API и передать ее в структуру VkApplicationInfo.

VkEnumerateInstanceVersion не для этого.

VkApplicationInfo::apiVersion указывает версию Vulkan, для которой написан ваш код. Эта версия должна быть фиксированным значением, потому что ваш код не может быть написан для версий Vulkan, которых еще не существует. То есть, если вы пишете приложение, работающее против 1.1, то вы указываете VK_VERSION_1_1.

Вы все еще можете получить версию 1.2, но это нормально, потому что все основные версии Vulkan обратно совместимы с более низкими младшими номерами версий. Поэтому, если вы напишете свой код для Vulkan 1.1, он будет работать на любой реализации 1.2.

Вы также неправильно используете версию экземпляра. Версия экземпляра — это версия механизма экземпляра Vulkan, а не реализации Vulkan в целом. Вы можете быть подключены к оборудованию экземпляра 1.2, но реализация устройства Vulkan может дать вам только 1.1. Это нормально, что касается Вулкана.

Что касается деталей вашего кода:

Этот код фактически не различает Vulkan 1.0 и Vulkan 1.1 правильно. Действительно, он содержит множество ошибок и запутанных битов.

Первая нерешенная потенциальная проблема — это возможность того, что реализация экземпляра слишком старая для поддержки vkEnumerateInstanceVersion. Поскольку эта функция не предусмотрена реализациями экземпляра Vulkan 1.0, вы должны сначала убедиться, что функция действительно существует. То есть вы должны проверить значение FN_vkEnumerateInstanceVersion перед его вызовом. Если функция не существует, версия экземпляра должна быть 1.0.

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

Как только вы идете, чтобы проверить фактическое значение, о котором идет речь, вы делаете что-то странное. Вы тестируете instanceVersion!=nullptr. Но в этом нет смысла, потому что это всегда будет указывать на действительную память. Поэтому делать из этого вывод о том, что версия реализации экземпляра 1.1, просто неправильно.

Значение номера версии в Vulkan четко указано в спецификации. В вашем случае, если вы просто ищете основной и дополнительный номера версий, вы можете отрезать номера версий патчей.

Таким образом, правильный код для получения версии экземпляра будет таким:

auto FN_vkEnumerateInstanceVersion = PFN_vkEnumerateInstanceVersion(vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"));

if (FN_vkEnumerateInstanceVersion == nullptr)
  return VK_API_VERSION_1_0;
else
{
  uint32_t instanceVersion;
  auto result = FN_vkEnumerateInstanceVersion(&instanceVersion);
  return instanceVersion & 0xFFFFF000; //Remove the patch version.
}

Итак, я неправильно понял vkspec. Спасибо! :-)

brightprogrammer 20.12.2020 18:29

@brightprogrammer: Пожалуйста, прочтите и мои последние правки.

Nicol Bolas 20.12.2020 18:30

@NicolBolas Спасибо за ваш ответ, он очень полезен. Однако я хочу отметить, что версия патча состоит из 12-битной, а не 16-битной версии. Таким образом, маска должна быть 0xFFFFF000.

Scillman 15.04.2022 18:27

Вы можете получить информацию о версии Vulkan из версии экземпляра, возвращаемой vkEnumerateInstanceVersion, с помощью 3 макросов, определенных в заголовке vulkan.

Вот фрагмент, который делает трюк:

uint32 instanceVersion = VK_API_VERSION_1_0;
auto FN_vkEnumerateInstanceVersion = PFN_vkEnumerateInstanceVersion(vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion"));
if (vkEnumerateInstanceVersion){
    vkEnumerateInstanceVersion(&instanceVersion );
}

// 3 macros to extract version info
uint32_t major = VK_VERSION_MAJOR(instanceVersion);
uint32_t minor = VK_VERSION_MINOR(instanceVersion);
uint32_t patch = VK_VERSION_PATCH(instanceVersion);

cout << "Vulkan Version:" << major << "." << minor << "." << patch << endl;

Это напечатает что-то вроде строк:

Vulkan Version:1.1.121

Другие вопросы по теме