如何从程序而不是 env var 中设置验证层?
How to set validation layers from within program rather than env var?
官方vulkan documentation声称:
Applications may programmatically activate layers via the vkCreateInstance() entry point.
这是设置环境变量的替代方法。但是,本节中没有其他关于如何设置它们的内容。我们可以改为阅读 official docs of VkCreateInstance which say nothing about validaiton layers, so we can look at the CreateInfo。在这里,唯一相关的字段似乎是 ppEnabledLayerNames
.
基于目前的一切,人们可能认为将正确的字符串传递给创建信息就足以设置图层。所以可以这样做:
const std::vector<const char*> VALIDATION_LAYERS = {"VK_LAYER_KHRONOS_validation"};
// Create Vulkan instance to communicate with the loader
vk::InstanceCreateInfo create_info = {};
create_info.pApplicationInfo = &program_info,
create_info.enabledLayerCount = static_cast<uint32_t>(VALIDATION_LAYERS.size()),
create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data(),
create_info.enabledExtensionCount = static_cast<uint32_t>(required_extensions.size()),
create_info.ppEnabledExtensionNames = required_extensions.data();
auto [result, instance] = vk::createInstanceUnique(create_info);
我 运行 上面的代码片段在一个更大的应用程序中。如果我按照文档中的描述手动设置环境变量,它就会运行。但是,如果我不设置 env var 而只依赖上面的代码片段,我的程序会在创建实例时崩溃。
由于文档明确表示您可以通过编程方式进行设置,但似乎没有说明如何设置,您应该怎么做才能避免依赖环境变量?
更具体地说,当 运行 片段出现在 hpp header 时,我得到的错误是断言失败:
typename vk::ResultValueType<vk::UniqueHandle<Type, Dispatch> >::type vk::createResultValue(vk::Result, T&, const char*, const typename vk::UniqueHandleTraits<Type, Dispatch>::deleter&) [with T = vk::Instance; D = vk::DispatchLoaderStatic; typename vk::ResultValueType<vk::UniqueHandle<Type, Dispatch> >::type = vk::ResultValue<vk::UniqueHandle<vk::Instance, vk::DispatchLoaderStatic> >; typename vk::UniqueHandleTraits<Type, Dispatch>::deleter = vk::ObjectDestroy<vk::NoParent, vk::DispatchLoaderStatic>]: Assertion `result == Result::eSuccess' failed.
使用 gdb 分析堆栈显示这发生在实例创建时。
导致断言失败的具体错误码是vk::Result::eErrorLayerNotPresent
.
作为附加信息,调用:auto [result, availableLayers] = vk::enumerateInstanceLayerProperties();
在调用实例创建之前立即returns一个空数组。
只需VkInstanceCreateInfo::ppEnabledLayerNames
启用图层。
图层必须可用才能启用。这可以通过 vkEnumerateInstanceLayerProperties
.
来确定
显然,Vulkan 并不神奇,Loader 需要知道在哪里寻找扩展。 LoaderAndLayerInterface.md.
中概述了该系统
基本上 Windows 它在注册表中查找规范路径。在 Linux 上,它在文件系统中查找规范路径。这些将由 SDK 的可安装版本设置。或者 VK_LAYER_PATH
环境变量可以覆盖默认路径。
官方vulkan documentation声称:
Applications may programmatically activate layers via the vkCreateInstance() entry point.
这是设置环境变量的替代方法。但是,本节中没有其他关于如何设置它们的内容。我们可以改为阅读 official docs of VkCreateInstance which say nothing about validaiton layers, so we can look at the CreateInfo。在这里,唯一相关的字段似乎是 ppEnabledLayerNames
.
基于目前的一切,人们可能认为将正确的字符串传递给创建信息就足以设置图层。所以可以这样做:
const std::vector<const char*> VALIDATION_LAYERS = {"VK_LAYER_KHRONOS_validation"};
// Create Vulkan instance to communicate with the loader
vk::InstanceCreateInfo create_info = {};
create_info.pApplicationInfo = &program_info,
create_info.enabledLayerCount = static_cast<uint32_t>(VALIDATION_LAYERS.size()),
create_info.ppEnabledLayerNames = VALIDATION_LAYERS.data(),
create_info.enabledExtensionCount = static_cast<uint32_t>(required_extensions.size()),
create_info.ppEnabledExtensionNames = required_extensions.data();
auto [result, instance] = vk::createInstanceUnique(create_info);
我 运行 上面的代码片段在一个更大的应用程序中。如果我按照文档中的描述手动设置环境变量,它就会运行。但是,如果我不设置 env var 而只依赖上面的代码片段,我的程序会在创建实例时崩溃。
由于文档明确表示您可以通过编程方式进行设置,但似乎没有说明如何设置,您应该怎么做才能避免依赖环境变量?
更具体地说,当 运行 片段出现在 hpp header 时,我得到的错误是断言失败:
typename vk::ResultValueType<vk::UniqueHandle<Type, Dispatch> >::type vk::createResultValue(vk::Result, T&, const char*, const typename vk::UniqueHandleTraits<Type, Dispatch>::deleter&) [with T = vk::Instance; D = vk::DispatchLoaderStatic; typename vk::ResultValueType<vk::UniqueHandle<Type, Dispatch> >::type = vk::ResultValue<vk::UniqueHandle<vk::Instance, vk::DispatchLoaderStatic> >; typename vk::UniqueHandleTraits<Type, Dispatch>::deleter = vk::ObjectDestroy<vk::NoParent, vk::DispatchLoaderStatic>]: Assertion `result == Result::eSuccess' failed.
使用 gdb 分析堆栈显示这发生在实例创建时。
导致断言失败的具体错误码是vk::Result::eErrorLayerNotPresent
.
作为附加信息,调用:auto [result, availableLayers] = vk::enumerateInstanceLayerProperties();
在调用实例创建之前立即returns一个空数组。
只需VkInstanceCreateInfo::ppEnabledLayerNames
启用图层。
图层必须可用才能启用。这可以通过 vkEnumerateInstanceLayerProperties
.
显然,Vulkan 并不神奇,Loader 需要知道在哪里寻找扩展。 LoaderAndLayerInterface.md.
中概述了该系统基本上 Windows 它在注册表中查找规范路径。在 Linux 上,它在文件系统中查找规范路径。这些将由 SDK 的可安装版本设置。或者 VK_LAYER_PATH
环境变量可以覆盖默认路径。