繁体   English   中英

WRL::ComPtr 导致 d3d 中的 object 泄漏?

[英]WRL::ComPtr causes object leaks in d3d?

我正在制作一个简单的 d3d 11 应用程序,并且正在使用 Microsoft::WRL::ComPtr 自动释放资源。 出于某种原因,尽管当应用程序退出时,我从 d3d 收到 30-40 条 Live Object 警告。 我可能会错过一两个,但这似乎更像是我拥有的所有对象的计数。 我显然做错了什么。 我的一般用法是在一些包装器 class 中有一个成员:

class graphics_device
{
   // ...
   ComPtr<ID3D11Device> hwdevice;
}

理论上应该在 class 破坏时释放 object。 (我在堆栈上创建了大多数对象,并且我仔细检查了我是否删除了堆上的对象)

当我创建我的功能时,我将它们作为参考传递。 例如:

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 根据评论,一个好的起点是object 命名 请记住 output 发生在 Direct3D 设备发布时,因此您可能需要查看“发布顺序”以使其干净退出。 还有“内部”与“外部”参考计数,因此它们可能会有些混乱。 有关调试层使用的一些说明,请参阅此博客文章

要记住的另一件事是 Direct3D object 报告不能真正告诉您有关 DXGI 拥有的对象的信息。 这就是为什么使用DXGI 调试设备也很有用的原因。

directx-vs-templates将这些博客文章中的所有建议放在一个地方,因此您可能需要查看它们。

最后,将ComPtr作为参数传递通常不是最好的用例,即使是通过引用也是如此。 使用ComPtr作为数据成员和局部变量很好,但通常作为参数最好使用“原始指针”,因为生命周期已经是隐式的。 所以你的 function 签名会更好:

void graphics_device::create_constant_buffer(u32 size, const void* data, ID3D11Buffer** constantBuffer);

然后在调用 function 时,您使用ComPtr

ComPtr<ID3D11Buffer> cb;
graphicsdevice->create_constant_buffer(size, data, &cb);

有关最有效地使用它的一些提示,请参阅ComPtr 上的这个 wiki

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM