微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何确保正确销毁vk :: UniqueBuffer和vk :: UniqueDeviceMemory

如何解决如何确保正确销毁vk :: UniqueBuffer和vk :: UniqueDeviceMemory

我遇到了以下难题,试图使用Vulkan Hpp唯一句柄来存储缓冲区及其分配的内存。我声明了句柄

vk::UniqueBuffer vertex_buffer;
vk::UniqueDeviceMemory vertex_buffer_memory;

,并使用vk::Device::createBufferUniquevk::Device::allocateMemoryUnique填充它们。由于后者取决于前者的内存要求(通过vk::Device::getBufferMemoryRequirements获得),因此需要按此顺序调用它们。但是,这导致vertex_memory_buffervertex_buffer之前被销毁,并触发来自验证层的以下警告:

Validation Warning: [ CHASSIS ] Object 0: handle = 0x558599c91fc0,type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x1b000000001b,type = VK_OBJECT_TYPE_BUFFER; Object 2: handle = 0x1c000000001c,type = VK_OBJECT_TYPE_DEVICE_MEMORY; | MessageID = 0x7366b7dd | 
VK Object VkBuffer 0x1b000000001b[] still has a reference to mem obj VkDeviceMemory 0x1c000000001c[].

实际上,我查找的所有C API示例都会先破坏缓冲区,然后释放内存。我当然可以使用某种变通办法来确保在此处进行相同的操作(例如,认初始化vertex_buffer_memory并在创建vertex_buffer之后分配给它),但这确实违背了唯一句柄的目的(正是为了使资源管理自动化)。除非我有误解,否则Vulkan API和RAII的设计之间似乎不兼容。解决此问题的正确方法是什么?

解决方法

需要按此顺序调用,因为后者取决于前者的内存要求

不,他们没有。您确实需要获得适合该缓冲区的内存要求,但是不需要使用特定于 VkBuffer的对象。

最好在应用程序启动时通过创建代表特定用例的VkBuffer来计算一次需求。也就是说,创建一些VkBuffer实例,它们代表您将要使用的所有种类缓冲区。

缓冲区的内存要求并不特定于该VkBuffer对象; bunch of rules in the Vulkan specification定义了两个VkBuffer的要求相同的环境。因此,如果您创建的VkBuffer与实际使用的类似,则可以获取该需求,并且知道为这些需求分配的内存将对您计划使用的内存起作用。

只需遵守这些规则,您就无需颠倒这些对象的初始化顺序。

此外,为一个缓冲区或图像分配内存几乎总是一个坏主意。 Vulkan不是OpenGL,因此您不应将vkAllocateMemoryvkCreateBuffer视为glBufferStorage。分配大块内存,然后根据需要将其细分为缓冲区(和图像)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。