You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调整D3D11程序窗口大小后关闭出现资源泄漏警告如何解决?

问题根因定位

你代码的核心泄漏点是每次窗口调整大小时,旧的深度模板视图(pZBuffer)没有被释放,每次resize都会新建一个深度模板视图对象,旧对象的引用计数始终不为0,所以调整窗口次数越多,泄漏的D3D对象越多,退出时的Live Object警告也会对应增多。

另外还有两个潜在问题需要同步修正:

  • 调用ResizeBuffers前需要确保GPU已经完成了所有渲染指令,避免对象被GPU占用导致释放失败
  • 释放旧对象前要做空指针判断,避免空指针访问崩溃

修复步骤

  1. 在ResizeBuffers调用前,除了释放后缓冲渲染视图pBackBufferRTView,还要同步释放旧的深度模板视图pZBuffer
  2. 释放对象前做空指针有效性判断,释放后把指针置空避免野指针
  3. 添加Flush指令清空GPU队列,确保所有资源引用都被解除

修正后的窗口调整核心代码

if (pSwapChain)
{
    // 先解绑渲染目标,清空GPU指令队列,确保资源没有被占用
    pImmediateContex->OMSetRenderTargets(0, 0, 0);
    pImmediateContex->Flush();

    // 释放旧的后缓冲渲染视图
    if (pBackBufferRTView)
    {
        pBackBufferRTView->Release();
        pBackBufferRTView = nullptr;
    }
    // 释放旧的深度模板视图【这是之前漏掉的核心步骤】
    if (pZBuffer)
    {
        pZBuffer->Release();
        pZBuffer = nullptr;
    }

    HRESULT hr = S_OK;
    //if 0, DXGI will use the width of the client area
    hr = pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);

    if (FAILED(hr)) return hr;

    //Get buffer and create a render-target-view
    ID3D11Texture2D* pBackBufferTexture;
    //Returns pointer to the back buffer 
    hr = pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBufferTexture);

    if (FAILED(hr)) return hr;

    //Use back buffer texture pointer to create the renedr target view
    hr = pD3DDevice->CreateRenderTargetView(pBackBufferTexture, NULL, &pBackBufferRTView);
    
    if (FAILED(hr)) return hr;
    //Clean up
    pBackBufferTexture->Release();
    pBackBufferTexture = nullptr;
     

    RECT rc;
    GetClientRect(hWnd, &rc);
    screenWidth = rc.right - rc.left;
    screenHeight = rc.bottom - rc.top;
    stringstream a;
    a << std::to_string(screenWidth) << " " << std::to_string(screenHeight) << "\n";
    OutputDebugString(a.str().c_str());
    camera->SetProjectionValues(90.0f, static_cast<float>(screenWidth) / static_cast<float>(screenHeight), 0.01f, 1000.0f);

    //Create a Z buffer texture 
    D3D11_TEXTURE2D_DESC tex2DDesc;
    ZeroMemory(&tex2DDesc, sizeof(tex2DDesc));

    tex2DDesc.Width = screenWidth;
    tex2DDesc.Height = screenHeight;
    tex2DDesc.ArraySize = 1;
    tex2DDesc.MipLevels = 1;
    tex2DDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; //24 bits of each pixel 
    tex2DDesc.SampleDesc.Count = 1;
    tex2DDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    tex2DDesc.Usage = D3D11_USAGE_DEFAULT;

    ID3D11Texture2D* pZBufferTexture;
    hr = pD3DDevice->CreateTexture2D(&tex2DDesc, NULL, &pZBufferTexture);

    if (FAILED(hr)) return hr;

    //Create the Z buffer
    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    ZeroMemory(&dsvDesc, sizeof(dsvDesc));

    dsvDesc.Format = tex2DDesc.Format;
    dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;

    pD3DDevice->CreateDepthStencilView(pZBufferTexture, &dsvDesc, &pZBuffer);
    pZBufferTexture->Release();
    pZBufferTexture = nullptr;

    // 新建完深度缓冲后再执行清空操作
    pImmediateContex->ClearDepthStencilView(pZBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

    //Set the render target view 
    pImmediateContex->OMSetRenderTargets(1, &pBackBufferRTView, pZBuffer);
    
    //Set the viewport
    D3D11_VIEWPORT viewport;
    viewport.TopLeftX = 0;
    viewport.TopLeftY = 0;
    viewport.Width = (FLOAT)screenWidth;
    viewport.Height = (FLOAT)screenHeight;
    viewport.MinDepth = .0f;
    viewport.MaxDepth = 1.0f;

    pImmediateContex->RSSetViewports(1, &viewport);
}

内容的提问来源于stack exchange,提问作者Adamska_01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:54:04