c++ - 带有 VK_NULL_HANDLE 的 Vulkan DestroyInstance/DestroyDevice

标签 c++ vulkan

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

2.5.1 Valid Usage

It is valid to pass VK_NULL_HANDLE to any vkDestroy* or vkFree* command, which will silently ignore these values.

但是,如果您使用 vkGetInstanceProcAddrvkGetDeviceProcAddr 来获取函数指针,会发生什么情况?我正在执行以下操作:

Device::Device(Device&& other) :
    handle(other.handle),
    functions(other.functions)
{
    other.handle = VK_NULL_HANDLE;
}

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

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

最佳答案

这是一个驱动程序错误。

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

请注意 vkDestroyDevice 的“有效用法”部分如何谈论设备可能是 NULL,而 vkDestroyCommandBufferPool 谈论池可能是VK_NULL_HANDLE。因此规范清楚地做出了这种区分。

这意味着 2.5.1 中的声明不是指引用采用可分派(dispatch)句柄的 vkDestroy* 函数。毕竟,它们不能假定值 VK_NULL_HANDLE

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

VkDevice dev = VK_NULL_HANDLE;

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

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

  • If device is not NULL, device must be a valid VkDevice handle

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

关于c++ - 带有 VK_NULL_HANDLE 的 Vulkan DestroyInstance/DestroyDevice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36561278/

相关文章:

c++ - "{" token 错误之前的预期类名

c++ - 是否可以简化这些 C++ 模板参数?

glsl - Vulkan 采样器的 maxLod 会不会太高?

synchronization - Vulkan:WAITING栅栏后提交的工作可以读取先前提交的写入吗?

Vulkan:支持 Sprite 的 alpha channel

来自 cppreference.com 的 C++ 结构初始化

c++ - 为什么ostream_iterator需要显式声明要输出的对象类型?

c++ - 如何检查动态属性是否存在

c++ - 在 Vulkan 中启用垂直同步

Vulkan 加载 vkCreateDebugReportCallbackEXT