Multithreading DirectX11资源发布多线程

Multithreading DirectX11资源发布多线程,multithreading,directx,Multithreading,Directx,我读过这本书 它声明我可以从多个线程调用ID3D11Device(除非使用了D3D11_CREATE_DEVICE_SINGLETHREADED),但是对ID3D11DeviceContext的调用必须包含一个关键部分 我还没有找到任何关于使用“释放”方法释放资源的信息,这些资源包括纹理、渲染目标、顶点/索引缓冲区、着色器 ID3D11Texture2D、ID3D11Texture3D、ID3D11ShaderResourceView、ID3D11RenderTargetView、ID3D11D

我读过这本书

它声明我可以从多个线程调用ID3D11Device(除非使用了D3D11_CREATE_DEVICE_SINGLETHREADED),但是对ID3D11DeviceContext的调用必须包含一个关键部分

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

ID3D11Texture2D、ID3D11Texture3D、ID3D11ShaderResourceView、ID3D11RenderTargetView、ID3D11DepthStencilView

ID3D11缓冲区

ID3D11VertexShader、ID3D11HullShader、ID3D11DomainShader、ID3D11PixelShader

1) 在渲染线程的ID3D11DeviceContext未使用这些资源时,我是否可以随时从任何线程调用这些资源的“Release”,而不使用关键部分

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


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

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

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

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

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

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

最好的答案是使用一个智能指针,比如,让使用给定资源的每个线程都有自己的
ComPtr
指向该资源。这样,您将遇到的唯一真正的特殊情况是在执行设备拆卸操作时(例如响应
DXGI\u错误\u设备\u已删除
或执行“干净退出”)


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

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

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

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

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

最好的答案是使用一个智能指针,比如,让使用给定资源的每个线程都有自己的
ComPtr
指向该资源。这样,您将遇到的唯一真正的特殊情况是在执行设备拆卸操作时(例如响应
DXGI\u错误\u设备\u已删除
或执行“干净退出”)