Vulkan DestroyInstance / DestroyDevice with VK_NULL_HANDLE

And*_*son 4 c++ vulkan

我的印象是你可以在 NULL 句柄上调用 Destroy / Free ,这将是一个空操作。

2.5.1 有效使用

将 VK_NULL_HANDLE 传递给任何 vkDestroy* 或 vkFree* 命令是有效的,它们将默默地忽略这些值。

但是如果你使用vkGetInstanceProcAddrvkGetDeviceProcAddr来获取函数指针会发生什么?我正在做以下事情:

Device::Device(Device&& other) :
    handle(other.handle),
    functions(other.functions)
{
    other.handle = VK_NULL_HANDLE;
}
Run Code Online (Sandbox Code Playgroud)

当然,当为原始设备调用析构函数时,它会将空句柄传递给特定于设备的vkDestroyDevice

目前,这给了我一个读取访问冲突,我不确定这是 AMD 的错、LunarG 的错还是我的错。

Nic*_*las 5

这是一个驱动程序错误。

可调度句柄(又名:指针)和不可调度句柄(又名:整数)之间存在区别。NDH 是一种可以存储VK_NULL_HANDLE.

请注意vkDestroyDevice“有效使用”部分如何谈论可能存在的设备NULL,而vkDestroyCommandBufferPool谈论可能存在的池VK_NULL_HANDLE。所以规范清楚地做出了区分。

这意味着 2.5.1 中的语句不是指引用vkDestroy*采用可调度句柄的函数。毕竟,他们无法承担价值VK_NULL_HANDLE

当然,VK_NULL_HANDLE恰好被定义为 0。而在 C++ 中,整型字面量 0 也兼作空指针常量。这意味着:

VkDevice dev = VK_NULL_HANDLE;
Run Code Online (Sandbox Code Playgroud)

是完全合法的。尽管 Vulkan 规范并不一定要这样做才有意义。

然而,这一切都无关紧要。为什么?因为vkDestroyDevice的“有效用法”部分包含以下声明:

  • 如果device不是NULL,则device必须是有效VkDevice句柄

这里的条件分明要求,device确实可以NULL。因此,如果在您执行此操作时某个实现崩溃,则该实现存在问题。

  • 我在 LunarG 网站上发布了错误报告,该问题已在 1.0.11 版本中得到解决。 (2认同)