如何/何时在DirectX中释放资源和资源视图

时间:2019-01-02 00:29:56

标签: c++ resources directx

我正在处理DirectX 11演示应用程序,偶然发现以下问题:
当我从一个文件创建一个着色器资源视图(比如说一个纹理)时,我必须像其他所有D3D11对象一样在使用后释放它。但是隐式创建的基础资源呢?

我可以想象三种情况:
+我应该不理会资源。通过调用someShaderResourceView->Release()
释放它 +我应该与着色器资源视图对象一起手动释放它。
+我应该立即释放它。尽管我觉得这不合理,但这似乎可行。

处理此问题的正确方法是什么?

编辑:我正在使用DirectXTex纹理加载库,但我想让问题更笼统。

ID3D11Resource *resource;
ID3D11ShaderResourceView *resourceView;
HRESULT result = CreateWICTextureFromFile(device, path.c_str(), &resource, &texture, 0);
//resource->Release(); ???

也可以使用旧的D3DX11函数CreateWICTextureFromFile(...)代替D3DX11CreateShaderResourceViewFromFile(...)

1 个答案:

答案 0 :(得分:0)

Direct3D使用引用计数(通过AddRefRelease)方法来控制对象生存期,但有一些特殊的怪癖,因为它不遵循常规组件对象模型({{ 3}})。

特别是,如果对对象的 only 引用是在设备上下文上使用它设置的(将其绑定到呈现管道),则不足以使其保持活动状态,因为这些方法没有不能增加/减少参考计数。参见COM。因此,您的程序需要保留对当前使用的Direct3D对象的其他引用。

另一个区别是,如果ID3D11Device因为其引用计数达到零而被销毁,那么对于所有ID3D11DeviceChild对象的引用计数是什么都无关紧要,并且这些对象在那个时候都是无效的点。

您还应该记住,Direct3D对象直到将来某个时候才被销毁(也就是它使用了lazy-destruction),因此即使引用计数为零,也可能需要花费几帧的时间才能将其完全清除。如果您要处理大量活动资源并且必须担心过度使用,这尤其重要-顺便说一句,您可以使用ID3D11DeviceContext::Flush强制完成待完成的销毁操作,但这不是提高性能的好习惯经常这样做。

TL; DR: ID3D11ShaderResourceView对象向引用的ID3D11Resource对象添加了引用计数,因此,只要SRV处于活动状态,资源也将保持活动状态。您只需要采用CreateWICTextureFromFile的返回对象之一,但是如果需要,也可以采用两者。有关更多信息,请参见WICTextureLoader模块的Microsoft Docs页。

  

这是学习使用wiki智能指针的一个很好的理由。如果正确使用,它会处理参考计数,因此在大多数情况下,您可以避免担心它。