WRL::ComPtr 导致 d3d 中的对象泄漏?
WRL::ComPtr causes object leaks in d3d?
我正在制作一个简单的 d3d 11 应用程序,我正在使用 Microsoft::WRL::ComPtr 自动释放资源。出于某种原因,当应用程序退出时,我从 d3d 收到 30-40 个实时对象警告。我可能会错过一两个,但这似乎更像是我拥有的所有物品的数量。我显然做错了什么。我的一般用法是在一些包装器中有一个成员 class:
class graphics_device
{
// ...
ComPtr<ID3D11Device> hwdevice;
}
理论上应该在 class 销毁时释放对象。 (我在堆栈上创建了大多数对象,并且我仔细检查了我是否删除了堆上的对象)
当我创建我的功能时,我将它们作为参考传递。例如:
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);
}
知道我遗漏了什么吗?
编辑:忘记 post 来自 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: ]
还有很多类似的。我在运行时没有收到任何其他警告。
获得 'clean exit' 可能有点挑战。如果使用正确,它不太可能是 ComPtr
。根据评论,object naming. Remember that the output happens when the Direct3D Device is released, so you may need to look at the 'release order' to get it to cleanly exit. There are also 'internal' vs. 'external' ref-counts so they can be a little confusing. See this blog post 是一个很好的起点,可以获取有关调试层用法的一些注释。
另一件要记住的事情是 Direct3D 对象报告不能真正告诉您 DXGI 拥有的对象。这就是为什么使用 DXGI Debug Device 也很有用。
The directx-vs-templates put all advice from these blog posts in one place, so you might want to look at them.
最后,即使通过引用,将 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);
有关最有效地使用它的一些提示,请参阅 this wiki on ComPtr。
我正在制作一个简单的 d3d 11 应用程序,我正在使用 Microsoft::WRL::ComPtr 自动释放资源。出于某种原因,当应用程序退出时,我从 d3d 收到 30-40 个实时对象警告。我可能会错过一两个,但这似乎更像是我拥有的所有物品的数量。我显然做错了什么。我的一般用法是在一些包装器中有一个成员 class:
class graphics_device
{
// ...
ComPtr<ID3D11Device> hwdevice;
}
理论上应该在 class 销毁时释放对象。 (我在堆栈上创建了大多数对象,并且我仔细检查了我是否删除了堆上的对象)
当我创建我的功能时,我将它们作为参考传递。例如:
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);
}
知道我遗漏了什么吗?
编辑:忘记 post 来自 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: ]
还有很多类似的。我在运行时没有收到任何其他警告。
获得 'clean exit' 可能有点挑战。如果使用正确,它不太可能是 ComPtr
。根据评论,object naming. Remember that the output happens when the Direct3D Device is released, so you may need to look at the 'release order' to get it to cleanly exit. There are also 'internal' vs. 'external' ref-counts so they can be a little confusing. See this blog post 是一个很好的起点,可以获取有关调试层用法的一些注释。
另一件要记住的事情是 Direct3D 对象报告不能真正告诉您 DXGI 拥有的对象。这就是为什么使用 DXGI Debug Device 也很有用。
The directx-vs-templates put all advice from these blog posts in one place, so you might want to look at them.
最后,即使通过引用,将 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);
有关最有效地使用它的一些提示,请参阅 this wiki on ComPtr。