c++ - WRL::ComPtr 导致 d3d 中的对象泄漏?
问题描述
我正在制作一个简单的 d3d 11 应用程序,并且正在使用 Microsoft::WRL::ComPtr 自动释放资源。出于某种原因,当应用程序退出时,我从 d3d 收到了 30-40 个 Live Object 警告。我可能会错过一两个,但这似乎更像是我拥有的所有对象的计数。我显然做错了什么。我的一般用法是在某个包装类中有一个成员:
class graphics_device
{
// ...
ComPtr<ID3D11Device> hwdevice;
}
理论上应该在类销毁时释放对象。(我在堆栈上创建了大多数对象,并且我仔细检查了我是否删除了堆上的对象)
当我创建我的功能时,我将它们作为参考传递。例如:
void graphics_device::create_constant_buffer(u32 size, const void* data, ComPtr<ID3D11Buffer>& constantBuffer)
{
D3D11_BUFFER_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = size;
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDesc.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA initData;
ZeroMemory(&initData, sizeof(initData));
initData.pSysMem = data;
device->CreateBuffer(&bufferDesc, &initData, &constantBuffer);
}
有什么我想念的想法吗?
编辑:忘记发布来自 d3d11 的警告:
D3D11 WARNING: Live Object at 0x0061D93C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x0061DBE4, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x0061DE8C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object : 31 [ STATE_CREATION WARNING #0: UNKNOWN]
DXGI WARNING: Live Producer at 0x005ADDC0, Refcount: 4. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live Object at 0x005B7FD0, Refcount: 2. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]
还有更多类似的。在运行时我没有收到任何其他警告。
解决方案
获得一个“干净的出口”可能有点挑战。ComPtr
如果使用正确,则不太可能。根据评论,一个好的起点是对象命名。请记住,输出发生在 Direct3D 设备被释放时,因此您可能需要查看“释放顺序”以使其干净地退出。还有“内部”与“外部”参考计数,因此它们可能会有些混乱。有关调试层使用的一些说明,请参阅此博客文章。
要记住的另一件事是 Direct3D 对象报告不能真正告诉您 DXGI 拥有的对象。这就是为什么使用DXGI 调试设备也很有用的原因。
directx-vs-templates将这些博客文章中的所有建议放在一个地方,因此您可能需要查看它们。
最后,ComPtr
即使通过引用,作为参数传递通常也不是最佳用例。ComPtr
用作数据成员和局部变量很好,但通常作为参数最好使用“原始指针”,因为生命周期已经是隐式的。所以你的函数签名会更好:
void graphics_device::create_constant_buffer(u32 size, const void* data, ID3D11Buffer** constantBuffer);
然后在调用该函数时,您使用ComPtr
:
ComPtr<ID3D11Buffer> cb;
graphicsdevice->create_constant_buffer(size, data, &cb);
有关最有效地使用它的一些提示,请参阅ComPtr 上的这个 wiki 。
推荐阅读
- javascript - 如何使用 React Hooks 执行错误边界
- c# - sqlite-net-pcl 查询返回正确的行数,但所有数据为空或 0
- jinja2 - 如何按内部列表中的第一项过滤列表列表?
- android - Firebase Phone Auth 不适用于 React Native 应用程序(reCAPTCHA 后屏幕保持白色)
- regex - 正则表达式从 PostgreSQL 11.0 中的列中捕获值
- python - Python:如何在 Selenium 中获取当前鼠标坐标?
- woocommerce - 我如何使这个角色具体化?
- visual-studio-code - VS Code 调试器到达第一个断点的速度极慢
- python - 变量在函数 python 中不起作用(我的代码有什么问题)
- sql - 在存储过程中设置事务级别时,被调用的过程是否保持相同的事务级别?