如何解决使用 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版本。 vulkan 规范指出:
// 由 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。此外,我正在检查版本 1.2.165
解决方法
我正在使用 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 而言,这很好。
至于您的代码的详细信息:
此代码实际上并未正确区分 Vulkan 1.0 和 Vulkan 1.1。事实上,它包含许多错误和令人困惑的部分。
第一个未解决的潜在问题是实例实现可能太旧而无法支持 vkEnumerateInstanceVersion
。由于 Vulkan 1.0 实例实现不提供此功能,因此您应首先确保该功能确实存在。也就是说,您应该在调用它之前检查 FN_vkEnumerateInstanceVersion
的值。如果该函数不存在,则实例版本必须为 1.0。
接下来,您调用该函数。但该功能不能失败;它只能返回错误代码 VK_SUCCESS
。所以检查它的结果代码是没有意义的。
一旦你去检查有问题的实际值,你就会做一些奇怪的事情。你测试instanceVersion!=nullptr
。但是这样做没有意义,因为它总是指向有效内存。所以由此得出的结论是实例实现版本是 1.1 是完全错误的。
Vulkan 中版本号值的含义是clearly specified in the specification。就您而言,如果您只是在寻找主要和次要版本号,您可以去掉补丁版本号。
所以获取实例版本的正确代码是:
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 & 0xFFFF0000; //Remove the patch version.
}
,
您可以使用 vulkan 标头中定义的 3 个宏从 vkEnumerateInstanceVersion 返回的实例版本中获取 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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。