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

Vulkan 设备丢失 = 缺少同步,但我不知道如何

如何解决Vulkan 设备丢失 = 缺少同步,但我不知道如何

我试着弄清楚,如何使用光线追踪。我拥有的是一个光栅化绘制的三角形(与 Vulkan 教程中显示的大部分相同,但重构为我自己的代码和实用程序函数)。由于窗口大小调整/最小化等原因,交换链的重新创建工作正常。

然后我添加底部加速结构的创建。从那时起,我收到了一些设备丢失错误,但并非总是如此......这是我的代码框架:

mainLoop:
- acquireNextimage
- renderWorld
- render gui
- present

acquireNextimage:
- signaling a semaphore "Image Available"

render gui:
- wait for fence "Gui"
- begin command buffer (use graphics queue)
- begin render pass
- bind pipeline (graphics)
- set viewport
- set scissor
- draw (2 triangles in my GUI yet)
- end render pass
- end command buffer
- reset fence "Gui"
- submit command buffer (waiting for semaphore "Image Available",signaling semaphore "Rendering Done",checking fence "Gui")

present:
- queue present (waiting for semaphore "Rendering Done")

renderWorld:
(actually this does not render anything yet,it just creates a vertex buffer,an index buffer,and creates the bottom acceleration strucutre for it - and caches it for further frames,so this code runs only once at start!)
- == vertexbuffer ==
- create buffer (usage transfer dst)
- get buffer memory requirements
- allocate memory (device local)
- bind buffer memory
- create buffer (usage transfer src) (this is my staging buffer)
- get buffer memory requirements
- allocate memory (host visible,host coherent) (this is my staging memory)
- bind buffer memory
- wait for fence "Transfer"
- begin command buffer (use dedicated transfer queue)
- copy buffer
- end command buffer
- reset fence "Transfer"
- submit command buffer (checking fence "Transfer")
- wait queue idle
- free stating memory
- destroy staging buffer
- == indexbuffer ==
- create buffer (usage transfer dst)
- get buffer memory requirements
- allocate memory (device local)
- bind buffer memory
- create buffer (usage transfer src) (this is my staging buffer)
- get buffer memory requirements
- allocate memory (host visible,host coherent) (this is my staging memory)
- bind buffer memory
- wait for fence "Transfer"
- begin command buffer (use dedicated transfer queue)
- copy buffer
- end command buffer
- reset fence "Transfer"
- submit command buffer (checking fence "Transfer")
- wait queue idle
- free stating memory
- destroy staging buffer
- == bottom acceleration structure ==
- get acceleration structure build sizes info
- create buffer (acceleration structure storage,shader device address)
- create acceleration structure (bottom level)
- create buffer (acceleration structure storage,shader device address) (this is my scratch buffer)
- wait for fence "BuildAcc"
- begin command buffer (use dedicated compute queue)
- pipeline barrier (transfer write -> acceleration structure write),don't kNow if I need it here
- build acceleration structures
- pipeline barrier (acceleration structure write -> shader read),don't kNow if I need it here
- end command buffer
- reset fence "BuildAcc"
- submit command buffer (checking fence "BuildAcc")
- wait queue idle                                      <------- here device lost
- destroy scratch buffer

所以,如果我注释掉“renderWorld”,一切正常。如果我让 renderWorld 进入,那么我会丢失一个设备(请参阅最后的“等待队列空闲”行)。但不是每次运行程序时。

如果我在“wait queue idle”这一行设置了一个断点,程序停在这一行后,我可以继续程序,一切正常。此外,如果我注释掉“构建加速结构”命令,则一切正常(当然,除了没有 acc 结构,但没有丢失设备)。

所以我不知道问题出在哪里。在我看来,我需要以某种方式同步某些东西,因为有了断点我可以运行它并且它可以工作。所以我理解的代码一定没问题。

除了缺少着色器绑定之外,也没有验证错误,但是因为我还没有使用它们(我还没有进行光线跟踪渲染),所以我应该没有问题。

设备丢失后,其他信号量不会重置,我的 gui 渲染路径也不再工作。

有人能告诉我,如果我错过了某个地方的同步吗?我怎么添加呢?我没有在这里复制整个代码,因为这将是大量代码:D Vulkan 非常棒。但是,如果您需要一些代码安宁,请索取,我可以将其粘贴到此处。

解决方法

在此期间我做了什么:

  • 重新构建 vulkan 的整个初始化代码(现在我使用 .hpp 而不是 .h,这会在编译时进行一些不错的类型检查)
  • 一切,每一行都是手工重新输入(没有复制粘贴),问题依旧
  • 我已经注释掉了光栅化渲染->没问题(但是问题出现在acquireNextImage和present中,所以我需要光栅化来解决问题)
  • 如果我注释掉加速结构的构建 -> 没问题
  • 如果我在 (!) 构建 acc 结构之后放置了一个断点,但是在同步区域(此时光栅化器无法运行,必须在 CPU 端等待)-> 没问题

我的结论:我错过了构建 Acc 结构和光栅化之间的一些同步。我不知道我在哪里错过它,因为我使用了不同的:

  • 队列系列(光栅化使用图形队列系列 0,acc 结构计算队列系列 1)
  • 不同的信号量(acc builder 和 rasterizer 有自己的信号量和栅栏)
  • 我还没有使用 acc 缓冲区,我只是创建了它。

我不知道,那里发生了什么。为什么一切都很好,如果我用断点暂停?因为,如果一个参数是错误的,我应该会遇到与断点相同的问题,对吗?所以我的理解是,同步有问题。但问题也在于,acquireNextImage 因 DeviceLost 错误而失败。这可能是一个错误的参数,超出范围的指针等。

我要深入调查……^^

,

我发现了问题!这是正确的提示和接缝,与我的问题相同:

https://www.reddit.com/r/vulkan/comments/fqu90h/submitting_command_buffer_to_compute_queue_for/

所以我没有为我的加速缓冲区分配内存,这里是:

- == bottom acceleration structure ==
- get acceleration structure build sizes info
- create buffer (acceleration structure storage,shader device address) <---- no memory

在我注意到 reddit 上的帖子之前,我已经为我的临时缓冲区分配了内存,因为我认为它是必需的,因为我从中获取了设备地址。但是在 Web 的某个地方,我读到了有关加速结构缓冲区的信息,它不需要任何内存分配,而且这是在幕后完成的。但事实并非如此:)

所以现在我的代码可以工作了,我现在可以继续学习和构建顶级加速结构:)

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