【问题标题】:d3dBuffer created with various sizes not released使用各种大小创建的 d3dBuffer 未发布
【发布时间】:2017-01-08 20:04:11
【问题描述】:

我注意到 DirectX api(来自 AMD 的驱动程序)存在问题。 如果我使用具有增量大小的 createBuffer() 创建 d3d 缓冲区并在 for 循环中释放它,内存诊断工具显示进程的私有字节大小在不断增加。我认为这可能是因为 GPU 映射的系统内存从未被释放。顺便说一句,cpu 堆大小是稳定的。

  1. FOR 1000 次迭代缓冲区大小从 1kb 到 1000 MB
  2. 使用 CreateBuffer D3D11_USAGE_STAGING/D3D11_USAGE_DYNAMIC & D3D11_CPU_ACCESS_WRITE
  3. d3dbuffer.Release & d3dbuffer = nullptr
  4. 上下文。 cleastate() 和 flush() 同步释放 d3dbuffer
for (unsigned long long totalSize = 1MB; totalSize <= 1000MB ; totalSize += 1MB)
{
    // create
    CComPtr<ID3D11Buffer> pd3dBuffer;
    D3D11_BUFFER_DESC bufferDesc;
    {
       ZeroMemory(&bufferDesc, sizeof(bufferDesc));
       bufferDesc.ByteWidth = static_cast<UINT>(bufferSize);
       bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
       bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
       bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
       bufferDesc.MiscFlags = 0;
       bufferDesc.StructureByteStride = 0;
    }
    HRESULT hr = pd3dDevice->CreateBuffer(&bufferDesc, NULL, pd3dBuffer);
    if (FAILED(hr)) break;

    //release
    pd3dBuffer.Release();
    pd3dDeviceContext->ClearState();
    pd3dDeviceContext->Flush();

}

因为进程内存使用量不断上升,最终达到我的物理内存 16gb 限制并崩溃。这很奇怪,因为我在创建后立即同步释放缓冲区。进程内存使用应该是比较稳定的。 有没有人可以解释directx内存管理是如何工作的?

【问题讨论】:

  • 等我看看文档
  • 映射后是否也要取消映射缓冲区?
  • 不涉及映射解映射。只是创建一个同步删除(不延迟)。
  • CreateD3D11Buffer 是您的功能之一。你应该发布它的代码。
  • 感谢查克,更新了!

标签: memory-leaks directx gpu amd direct3d


【解决方案1】:

经过一番调查,这种奇怪的行为是由 DirectX 实现引起的。基本上微软作为一家操作系统公司只定义 DirectX API 的接口/规范,第 3 方 GPU 供应商必须提供他们自己的这些 API 实现。

Nvidia会提供一个,AMD会提供一个,如果突然高通要支持DirectX,它也必须写一个。

DirectX 规范中没有完全定义缓冲区分配和释放机制,因此由供应商提供最佳内存管理算法。由于供应商的实现中存在一个错误,即不回收释放的内存句柄,因此与缓冲区关联的系统提交的内存没有被释放,这导致了这个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2019-03-22
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多