C++ 片段着色器的输出并不总是正确显示(下面有很多细节)(找到了解决方案)

C++ 片段着色器的输出并不总是正确显示(下面有很多细节)(找到了解决方案),c++,synchronization,shader,driver,vulkan,C++,Synchronization,Shader,Driver,Vulkan,所以,事情是这样的:我正在开发一个游戏引擎,用于学习,这是一种爱好。该引擎使用OpenGL和Vulkan。我目前正在Vulkan开发PBR渲染器。它已经工作了很长时间,直到我重构它 这就是问题所在:我有几个统一的缓冲区,我想测试我是否正确地接收了它们。但是其中一些是不正确的,比如灯光颜色,伽马,等等,输出是一片漆黑,而另一些,比如灯光位置,是正确的,显示的颜色是正确的 所以我想这可能是制服的问题。我启动了RenderDoc,结果表明,在捕获帧时,我不仅正确地接收了所有数据,而且swapchain

所以,事情是这样的:我正在开发一个游戏引擎,用于学习,这是一种爱好。该引擎使用OpenGL和Vulkan。我目前正在Vulkan开发PBR渲染器。它已经工作了很长时间,直到我重构它

这就是问题所在:我有几个统一的缓冲区,我想测试我是否正确地接收了它们。但是其中一些是不正确的,比如灯光颜色,伽马,等等,输出是一片漆黑,而另一些,比如灯光位置,是正确的,显示的颜色是正确的

所以我想这可能是制服的问题。我启动了RenderDoc,结果表明,在捕获帧时,我不仅正确地接收了所有数据,而且swapchain图像上的结果也是正确的,所以问题在于:数据在显示过程中丢失,或者我显示了一个不完整的图像,RenderDoc只是等待了足够长的时间,才捕获到正确的结果

所以我假设你有一个同步问题。这个系统的工作方式是这样的(几乎完全复制自vulkan-tutorial.com,只是它被分解成了类):

  • 我等待当前帧的围栏
  • 我获取下一幅图像,为这帧提供信号量
  • 如果需要,我会重新创建交换链
  • 我记录此帧的命令缓冲区(由于上下文正在动态更改,因此需要重新记录)
  • 我重置了这个框架的围栏
  • 我使用等待和信号量提交作品
  • 我使用前面的信号量作为等待信号量来显示结果
  • 我增加当前帧
每个交换链图像有一个信号灯和栅栏

由于这很容易成为驱动程序或操作系统的问题,以下是我的规格: 我正在使用Windows10Pro,64位(Build19041),GPU是GTX10603GB,我的驱动程序版本是456.71。该程序是在Visual Studio 2019预览版中开发的。我可以链接GitHub repo或RenderDoc捕获

简单回顾一下:我正确地接收了每个制服,但其中一些制服显示为黑色(事实上,0,0,0,因为添加0.5会产生灰色),其中一些制服显示正确,但根据RenderDoc,数据是正确的,捕获后的交换链图像是正确的,所以问题就在演讲时出现了

有人知道是什么导致了这个问题吗?这真的是同步吗?还有别的吗?我不认为我能给出一个最小的可复制的例子,因为源代码非常大,而且很复杂,但是如果你想要什么,问一下,我会添加细节


编辑:这不是同步问题。更新统一缓冲区的代码覆盖了整个缓冲区,我不知道RenderDoc如何显示正确的数据,一些描述符仍然有效。因此,如果您有类似的问题,请仔细检查代码中的VkMapMemory()、memcpy()和VkUnmapMemory()部分。

您使用什么加载程序?格雷夫还是什么?要将缓冲区传输到卡,您使用了什么功能?GLEW用于窗口。我使用VulkanSDK访问验证层和其他东西。制服基本上使用主机一致性和可见内存,并使用内存映射进行更改。(vkMapMemory,memset,vkUnmapMemory)我没有使用vulkan的东西,所以idkDo你有版本控制系统吗?您可以尝试进行git二等分以找到中断提交。我正在使用GitHub,它可以与以前的版本进行git差异,以查明破坏代码的更改。然而,这并不是那么容易。有一个巨大的更新,Vulkan接口改变了很多,着色器也改变了,我从PBR管道中删除了几何体着色器,实际上我没有试图解决这个问题,所以这会有问题。