我什么时候应该使用VULKAN_HPP_NO_EXCEPTIONS?

Con*_*tin 0 c++ exception-handling vulkan

这个问题是关于Vulkan-Hpp中的异常处理(官方的Vulkan C++绑定).

我在没有VULKAN_HPP_NO_EXCEPTIONS定义的情况下使用Vulkan-Hpp编写了一个小应用程序(并使用异常处理程序).但是在遇到这个stackoverflow问题(C++中的异常真的很慢)后,我开始担心在那里使用异常会受到惩罚.然后我发现了define VULKAN_HPP_NO_EXCEPTIONS,但它完全改变了所有可能引发异常的调用的语法(因为返回值不同):这意味着,必须在开始实现之前决定使用VULKAN_HPP_NO_EXCEPTIONS与否(即它们可以' t为"Debug"配置启用,轻松禁用"Release"配置.

如果通过定义VULKAN_HPP_NO_EXCEPTIONS ResultValue<SomeType>::type是一个结构来禁用异常处理,该结构包含字段result和value中的返回值和错误代码.

资源

surface = instance.createWin32SurfaceKHR(surfaceCreateInfo);
Run Code Online (Sandbox Code Playgroud)

vk::ResultValue<vk::SurfaceKHR> surfaceResult = instance.createWin32SurfaceKHR(surfaceCreateInfo);
if (surfaceResult.result == vk::Result::eSuccess) {
  surface = surfaceResult.value;
}
Run Code Online (Sandbox Code Playgroud)

因此,考虑到VULKAN_HPP_NO_EXCEPTIONS在开发的后期改变策略并非易事,我想知道我应该在哪些情况下使用VULKAN_HPP_NO_EXCEPTIONS我的项目以及在哪些情况下我不应该这样做?

我认为除了个人品味/意见之外,必须有一些技术原理.

Nic*_*las 5

可以禁用异常的主要原因是因为许多针对各种平台的游戏开发人员在编译器级别关闭了异常处理.在某些平台上,不支持异常处理.这些平台仍然需要一种合理的方法来处理错误,这需要不同的API.

在C++中,例外一直是一个备受争议的主题,而且可能永远都是如此.虽然C++程序员会同意异常只应在特殊情况下使用,但"特殊情况"和"预期行为"之间的界限最终是在旁观者眼中.

就个人而言,我认为Vulkan错误是"特殊情况".设备丢失和OOM错误不是您经常发生的事情.此外,您对他们的回应很可能是非本地的; 调用堆栈中较高的代码将实际处理它.

此外,许多错误的函数不是性能关键的Vulkan代码(vkCmd*等等)中常见的函数.毕竟,使用错误应该由验证层处理,并且在运行时应该是不可能的.通常会为对象创建/销毁和分配提供错误,这些错误不是您在构建命令缓冲区的过程中所做的事情.

最有可能在性能关键代码中找到的错误函数是vkAllocateDescriptorSets.虽然它可以出错,但只能出于内存碎片的原因.该标准实际上要求:

除了VK_ERROR_OUT_OF_POOL_MEMORY_KHRVK_ERROR_FRAGMENTED_POOL不暗示其通常含义之外的任何返回错误:应用程序应假定分配由于碎片而失败,并创建新的描述符池.

如果您可以完全控制输入数据,那么碎片就是您通常可以阻止的.有了这样的控制,您可以确保从描述符池分配时永远不会出错.

vkBegin/EndCommandBuffer可能会出错,但仅限于OOM原因.这通常意味着您无法恢复,因此性能无关紧要.

为您提供需要操作的严重运行时错误的命令通常是设备命令.而且你不会在渲染过程中发出这样的命令; vkQueueSubmit是一个例外,那是在渲染结束时(或开始;但是你想要看到它).

这可能是为什么抛出VK_HPP是默认值.