这个问题与Vulkan-Hpp中的异常处理有关(官方的Vulkan C ++绑定)。
我使用Vulkan-Hpp编写了一个小应用程序,但未定义VULKAN_HPP_NO_EXCEPTIONS
(并使用异常处理程序)。但在遇到这个stackoverflow问题(Are Exceptions in C++ really slow)后,我开始担心在那里使用异常会受到惩罚。然后我发现了define VULKAN_HPP_NO_EXCEPTIONS
,但它完全改变了所有可能引发异常的调用的语法(因为返回值不同):这意味着,必须在开始实现之前决定使用{{是不是1}}(即不能为“调试”配置启用它们,并且很容易为“释放”配置禁用它们。)
如果通过定义
VULKAN_HPP_NO_EXCEPTIONS
禁用异常处理VULKAN_HPP_NO_EXCEPTIONS
是包含返回的结构 值和字段结果和值中的错误代码。
即。
ResultValue<SomeType>::type
变为
surface = instance.createWin32SurfaceKHR(surfaceCreateInfo);
因此,考虑到在开发的后期更改vk::ResultValue<vk::SurfaceKHR> surfaceResult = instance.createWin32SurfaceKHR(surfaceCreateInfo);
if (surfaceResult.result == vk::Result::eSuccess) {
surface = surfaceResult.value;
}
的策略并非易事,我想知道在哪些情况下我应该VULKAN_HPP_NO_EXCEPTIONS
用于我的项目以及在哪些情况下我不应该'吨?
我认为除了个人品味/意见之外,必须有一些技术原理。
答案 0 :(得分:5)
可以禁用异常的主要原因是因为许多用于各种平台的游戏开发人员在编译器级别关闭了异常处理。在某些平台上,不支持异常处理。这些平台仍然需要一种合理的方法来处理错误,这需要不同的API。
在C ++中,例外一直是一个备受争议的主题,而且可能永远都是如此。虽然C ++程序员会同意异常只应在特殊情况下使用,但特殊情况和特殊环境之间存在差异。和&#34;预期的行为&#34;最终是在旁观者的眼中。
就个人而言,我会认为Vulkan错误是特殊情况&#34;。设备丢失和OOM错误不是您经常发生的事情。此外,您对他们的回应很可能是非本地的;调用堆栈中较高的代码将实际处理它。
此外,许多错误的函数不在性能关键的Vulkan代码(vkCmd*
等)中经常遇到的函数。毕竟,使用错误应该由验证层处理,并且在运行时应该是不可能的。通常会为对象创建/销毁和分配提供错误,这些错误不是您在构建命令缓冲区的过程中所做的事情。
最有可能在性能关键代码中找到的错误函数是vkAllocateDescriptorSets
。虽然它可以出错,但只能出于内存碎片的原因。标准实际需要这个:
除了
VK_ERROR_OUT_OF_POOL_MEMORY_KHR
或VK_ERROR_FRAGMENTED_POOL
之外的任何返回错误并不意味着它的通常含义:应用程序应该假定分配由于碎片而失败,并创建一个新的描述符池。
如果您可以完全控制输入数据,那么碎片就是您通常可以阻止的。有了这样的控制,您可以确保从描述符池分配时永远不会出错。
vkBegin/EndCommandBuffer
可能会出错,但仅限于OOM原因。这通常意味着您无法恢复,因此性能无关紧要。
为您提供需要操作的严重运行时错误的命令通常是设备命令。并且你不会在渲染过程中发出这样的命令; vkQueueSubmit
是一个例外情况,它是 end 的渲染(或开始;但是你想要看到它)。
这可能是抛出VK_HPP的原因。