我的印象是你可以在 NULL 句柄上调用 Destroy / Free ,这将是一个空操作。
2.5.1 有效使用
将 VK_NULL_HANDLE 传递给任何 vkDestroy* 或 vkFree* 命令是有效的,它们将默默地忽略这些值。
但是如果你使用vkGetInstanceProcAddr和vkGetDeviceProcAddr来获取函数指针会发生什么?我正在做以下事情:
Device::Device(Device&& other) :
handle(other.handle),
functions(other.functions)
{
other.handle = VK_NULL_HANDLE;
}
Run Code Online (Sandbox Code Playgroud)
当然,当为原始设备调用析构函数时,它会将空句柄传递给特定于设备的vkDestroyDevice。
目前,这给了我一个读取访问冲突,我不确定这是 AMD 的错、LunarG 的错还是我的错。
这是一个驱动程序错误。
可调度句柄(又名:指针)和不可调度句柄(又名:整数)之间存在区别。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
。因此,如果在您执行此操作时某个实现崩溃,则该实现存在问题。