这个问题有点抽象,但我在这里很困惑,所以我想我应该问一问。
上下文
我使用OpenGL从模拟器呈现内容,然后从GPU内存读取框架缓冲区并将其写入CPU。当我使用glGetTexImage从GPU内存读取框架缓冲区时,我遇到了这个问题。如果你真的想深入的话,这是代码是有问题的。
问题
在虚幻引擎中,有东西阻止了我对glGetTexImage的调用(将纹理从gpu内存复制到cpu内存)。我使用的是一个独立的渲染器和线程,而不是虚幻引擎使用的,所以我认为它不会冲突。我认为这与引擎如何与呈现线程同步有关。下面我有一些证据。
证据与理论
Y轴是每个调用以毫秒为单位的时间,x轴是实时的。绿色图是我对glGetTexImage的调用。蓝线是gamethread处理帧的时间,红线是渲染线程处理帧的时间。在这个例子中,我完全是GPU绑定的,根据分析器,游戏线程只是在等待渲染线程(未显示)。根据这个图表,看起来glGetTexImage被搁置,直到大约,一个或两个帧被呈现为。我知道在虚幻引擎文档里写着
在虚幻引擎4 (UE4)中,整个渲染器在自己的线程中操作,即游戏线程后面的一两个帧。

任何指导都会有帮助。
如果你有任何想法或建议,我很乐意听到你的意见,我并不指望任何人知道这里到底出了什么问题。我不知道在执行什么机制来停止对glGetTexImage的调用,直到虚幻引擎呈现了一两个帧。这两个渲染器在它们的操作中是完全相互排斥的,我真的不知道其中一个如何影响另一个的操作。这可能是一个副作用,基于我的图形驱动程序的工作方式或其他。我尝试使用DirectX11和Vulkan作为虚幻引擎渲染器,它们都会导致同样的问题。如果有人知道发生了什么,或者知道任何好的调试工具,可以诊断是什么阻塞了调用,我会非常感激的。
发布于 2020-12-04 18:32:38
任何使用指向客户端内存的指针的OpenGL函数都必须在将控制返回到您的CPU之前访问该指针。因此,当您对呈现到的图像调用glGetTexImage时,GPU必须总结整个呈现过程,然后将呈现的数据复制到内存中。
尽管有不同的线程向GPU发送工作,但GPU本身可能只能在任何特定时间完成一组工作。因此,它可以在其认为合适的情况下交错执行工作,而来自一个来源的工作的竞争可能需要等待另一个来源的工作完成。
因此,如果UE和您自己在GPU上抛出一些渲染命令,那么UE的工作可能首先到达了GPU。这意味着,当您等待您的工作完成,您也在等待UE的工作完成。
即使GPU允许多个工作队列同时完成,UE的工作仍将消耗您的工作中的一些GPU资源。它将使用着色器执行单位和ROPs,您的工作可能已经使用。
简而言之,如果UE的工作不影响glGetTexImage呼叫,我会更加惊讶。
如果需要避免延迟CPU线程,则需要从呈现目标进行异步读取。这意味着在像素传递中执行缓冲对象,然后等待检查栅栏同步对象完成传输,然后再从缓冲区读取数据。
https://stackoverflow.com/questions/65148749
复制相似问题