【问题标题】:DirectX11 resource Release Multi-ThreadingDirectX11 资源释放多线程
【发布时间】:2018-11-14 09:11:45
【问题描述】:

我读过https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-render-multi-thread-intro

它声明我可以从多个线程调用 ID3D11Device(除非使用了 D3D11_CREATE_DEVICE_SINGLETHREADED),但对 ID3D11DeviceContext 的调用必须用临界区包围。

我还没有找到任何关于释放资源的信息,使用他们的“释放”方法,用于纹理、渲染目标、顶点/索引缓冲区、着色器等资源。

ID3D11Texture2D、ID3D11Texture3D、ID3D11ShaderResourceView、ID3D11RenderTargetView、ID3D11DepthStencilView

ID3D11缓冲区。

ID3D11VertexShader、ID3D11HullShader、ID3D11DomainShader、ID3D11PixelShader。

1) 当渲染线程的 ID3D11DeviceContext 未使用这些资源时,我是否可以随时从任何线程调用这些资源的“释放”而不使用临界区?

2) 即使在渲染线程中 ID3D11DeviceContext 正在使用这些资源时,我是否可以从其他线程调用“释放”?

或者我是否需要使用用于访问 ID3D11DeviceContext 的相同关键部分来包围 Release 调用?

【问题讨论】:

    标签: multithreading directx


    【解决方案1】:

    COM 引用计数的内部实现通常以线程安全的方式(原子递增/递减)完成,因此从多个线程调用AddRefRelease 是安全的。

    当然,如果 refcount 变为 0,那么你就会有一个对象销毁,所以如果你有多个线程使用相同的资源,那么它具有适当数量的引用计数来保持它的生命是很重要的。在 Direct3D 中,对象销毁通常是延迟销毁,因此实际的对象清理可能不会在几帧内发生,但如果有人引用它,您仍应保持非零引用计数。

    Direct3D 11 使用与 Direct3D 10 相同的规则。它对管道集方法使用“弱引用”,因此仅在设备上下文中设置资源足以增加其引用计数. IOW:如果您有两个线程都使用相同的资源进行渲染,那么每个线程都必须在对象上保存一个引用计数,以保持它在任何给定时刻在设备上下文中“活动设置”的“活动”。

    它以这种方式工作以避免在每个渲染帧中不断增加/减少引用计数的开销。在 Direct3D 9 中,这种情况每帧发生数千次或更多。

    此外,如果ID3D11Device 达到零引用计数,则无论单个设备子引用计数如何,它和它的所有子对象都会被释放。

    Microsoft Docs

    最好的答案是使用像Microsoft::WRL::ComPtr 这样的智能指针,并让每个使用给定资源的线程都有自己的ComPtr 指向该资源。这样,您将遇到的唯一真正的特殊情况是在进行设备拆卸时(例如回复DXGI_ERROR_DEVICE_REMOVED 或执行“干净退出”)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 2012-01-08
      • 2012-05-04
      相关资源
      最近更新 更多