ID3D11DeviceContext :: Map slow performance

时间:2016-11-25 16:01:58

标签: c++ windows directx desktop

我正在使用桌面复制将屏幕内容复制到内存中的位图。我接收桌面纹理,然后创建一个分段纹理,使用CopyResource将桌面纹理复制到分段纹理,最后调用ID3D11DeviceContext::Map来访问分段纹理位并复制它们。几乎与此处描述的方式相同:https://stackoverflow.com/a/27283837/825318

问题是Map通话需要花费大量时间 - 对于大型显示​​器分辨率(如4K),每次通话可能需要100毫秒,这是不可接受的高,因为我需要确保30 fps的速度。

有没有办法让纹理内容更快?如果没有,有没有办法提供我自己的映射地址指针,以便系统复制纹理数据?感谢

2 个答案:

答案 0 :(得分:5)

很可能Map操作正在等待CopyResource完成。您可以使用GPUView来验证这一点。如果是这种情况,那么推荐的解决方案是接受有利于帧率的延迟。处理此问题的方法是保留至少3个分段纹理,并按以下方式在它们之间旋转:

第1帧 - 开始复制资源到分段纹理#1

第2帧 - 开始复制资源到分段纹理#2

第3帧 - 启动复制资源到登台纹理#3并映射登台纹理#1以访问数据

第4帧 - 开始复制资源到暂存纹理#1(旧内容应该已经保存)和地图分段纹理#2来访问数据

通过这种方式,您可以保持30 FPS,但会引入大约130毫秒的延迟,这对于大多数应用来说是可以接受的。

答案 1 :(得分:0)

我遇到了同样的问题,但是由于我正在执行DXGI桌面复制,因此此处建议的所有方法以及Microsoft提出的方法均不适用,因为没有“渲染线程”。

但是,对于这两种解决方案,由于将延迟保持在绝对最低水平,因此比其他建议要好得多,它是尝试使用D3D11_MAP_FLAG_DO_NOT_WAIT进行映射并检查DXGI_ERROR_WAS_STILL_DRAWING。您可以在一个紧密的循环中执行此操作,它不会使管道停滞。为避免浪费过多的CPU时间,请将睡眠/延迟放入循环中。