我正在编写一个带有两个线程的 DirectX 应用程序:
生产者线程使用 DirectX 抓取桌面框架(如 Desktop Duplication DirectX sample 中所示)
IDXGIResource* DesktopResource = nullptr; ID3D11Texture2D *m_AcquiredDesktopImage = nullptr; HRESULT hr = m_DeskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource); hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage)); DesktopResource->Release(); // The texture pointer I'm interested is m_AcquiredDesktopImage
消费者线程在 GPU 上执行图像处理操作。
为了避免复制,我想尽可能将所有内容都保留在 GPU 上。来自 ReleaseFrame的文档我有点明白我应该在处理完框架后立即在桌面复制界面上调用 ReleaseFrame
。
我的问题:我是否应该将 m_AcquiredDesktopImage
纹理复制到另一个纹理中,并在复制完成后立即调用 ReleaseFrame
并将新纹理返回给生产者线程进行处理或者我可以直接将 m_AcquiredDesktopImage
纹理指针返回给消费者线程吗?这是帧缓冲区纹理的拷贝,还是帧缓冲区纹理,我可能会通过返回它来生成数据竞争?
哪一个是处理抓取帧的生产者和 GPU 纹理的消费者的正确方法?
最佳答案
...should I copy the m_AcquiredDesktopImage texture into another one and call ReleaseFrame as soon as the copy is finished and return that new texture to the producer thread for processing or...
是的,就是这样。你得到了你的纹理,你已经完成了它并释放它,因为数据在释放后不再有效。
...can I just get away with returning the m_AcquiredDesktopImage texture pointer to the consumer thread? Is this a copy of the framebuffer texture or is it the framebuffer texture and I might generate a data race by returning it?
API 不断更新这个纹理。我们向您 promise ,从 AcquireNextFrame
成功返回到您的 ReleaseFrame
调用 API 不会触及纹理,您可以自由使用它。如果您无法在上述调用之间完成您的使用(这是您的情况,毕竟您创建了一个异步运行的消费者线程来捕获),您可以复制数据和 ReleaseFrame
。发布后,API 将恢复更新。
在 ReleaseFrame
之后尝试使用纹理将导致并发访问纹理、您和 API 的进一步更新。
关于c++ - 具有 DirectX 桌面框架的消费者-生产者线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50331632/