2017-11-11 511 views
1

我有点学习Direct3D,并有这个相当基本的代码,没有太花哨。在Visual Studio中进行调试时,我注意到有一个constantly increasing memory usage,这有点奇怪。IDXGISwapChain ::目前的内存泄漏

从我观察到的,IDXGISwapChain::Present分配每个帧更新新的内存块。约12秒差距。

我不知道这可能是什么原因,也许我忘了调用某种清算功能?我什至没有任何缓冲区或着色器或类似的东西,只是基本的初始化东西。我真的很想知道我该如何解决这个问题。这里是整个代码:

//============================================================================== 
// main.cpp 
// Copyright (c) Michael Loda. All rights reserved. 
//============================================================================== 

#if defined(DEBUG) || defined(_DEBUG) 
#define ALC_DEBUG 1 
#else 
#define ALC_DEBUG 0 
#endif 


#include <crtdbg.h> 

#define _WIN32_WINNT 0x0601 
#define WIN32_LEAN_AND_MEAN 
#include <Windows.h> 
#include <ShlObj.h> 
#include <comdef.h> 
#include <wrl.h> 

#include <d3d11.h> 
#include <DirectXMath.h> 
#include <DirectXColors.h> 


using Microsoft::WRL::ComPtr; 


HWND g_WindowHandle = NULL; 
LPCSTR g_WindowClassName = "WindowClass"; 

ComPtr<ID3D11Device> g_D3DDevice; 
ComPtr<ID3D11DeviceContext> g_D3DDeviceContext; 
ComPtr<IDXGISwapChain> g_D3DSwapChain; 
ComPtr<ID3D11RenderTargetView> g_D3DRenderTargetView; 
ComPtr<ID3D11Texture2D> g_D3DDepthStencil; 
ComPtr<ID3D11DepthStencilView> g_D3DDepthStencilView; 


LRESULT CALLBACK WindowProc(HWND p_Window, UINT p_Msg, WPARAM p_WParam, LPARAM p_LParam); 


int APIENTRY WinMain(HINSTANCE p_Inst, HINSTANCE, LPSTR p_CmdLine, int p_Show) 
{ 

#if ALC_DEBUG 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 
#endif 

    if (FAILED(CoInitializeEx(NULL, COINITBASE_MULTITHREADED))) 
     return 1; 



    HRESULT _Result = S_OK; 


    UINT _DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; 

#if ALC_DEBUG 
    _DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; 
#endif 

    if (FAILED(_Result = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, _DeviceFlags, NULL, 0, D3D11_SDK_VERSION, g_D3DDevice.GetAddressOf(), NULL, g_D3DDeviceContext.GetAddressOf()))) 
     throw _Result; // TODO: Handle 

#if ALC_DEBUG 
    ComPtr<ID3D11Debug> _D3DDebug; 
    if (FAILED(_Result = g_D3DDevice->QueryInterface(IID_PPV_ARGS(_D3DDebug.GetAddressOf())))) 
     throw _com_error(_Result); // TODO: Handle 
#endif 

    WNDCLASSEXA _WindowClass = {}; 
    _WindowClass.cbSize = sizeof(_WindowClass); 
    _WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
    _WindowClass.lpfnWndProc = WindowProc; 
    _WindowClass.cbClsExtra = 0; 
    _WindowClass.cbWndExtra = 0; 
    _WindowClass.hInstance = p_Inst; 
    _WindowClass.hIcon = LoadIconA(NULL, IDI_APPLICATION); 
    _WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW); 
    _WindowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
    _WindowClass.lpszMenuName = NULL; 
    _WindowClass.lpszClassName = g_WindowClassName; 
    _WindowClass.hIconSm = LoadIconA(NULL, IDI_APPLICATION); 

    if (!RegisterClassExA(&_WindowClass)) 
     throw; // TODO: Handle 

    g_WindowHandle = CreateWindowExA(0, g_WindowClassName, "", WS_POPUP, 0, 0, 1280, 720, NULL, NULL, p_Inst, NULL); 
    if (!g_WindowHandle) 
     throw; // TODO: Handle 


    { 
     ComPtr<IDXGIDevice> _DXGIDevice; 
     if (FAILED(_Result = g_D3DDevice->QueryInterface(IID_PPV_ARGS(_DXGIDevice.GetAddressOf())))) 
      throw _Result; // TODO: Handle 

     ComPtr<IDXGIAdapter> _DXGIAdapter; 
     if (FAILED(_Result = _DXGIDevice->GetAdapter(_DXGIAdapter.GetAddressOf()))) 
      throw _Result; // TODO: Handle 
     _DXGIDevice.Reset(); 

     ComPtr<IDXGIFactory> _DXGIFactory; 
     if (FAILED(_Result = _DXGIAdapter->GetParent(IID_PPV_ARGS(_DXGIFactory.GetAddressOf())))) 
      throw _Result; // TODO: Handle 
     _DXGIAdapter.Reset(); 


     DXGI_SWAP_CHAIN_DESC _SwapChainDesc = {}; 
     _SwapChainDesc.BufferDesc.Width = 1280; // TODO: Change 
     _SwapChainDesc.BufferDesc.Height = 720; // TODO: Change 
     _SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; // TODO: Change 
     _SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 
     _SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // TODO: SRGB? 
     _SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
     _SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_STRETCHED; 
     _SwapChainDesc.SampleDesc.Count = 1; // TODO: Change 
     _SwapChainDesc.SampleDesc.Quality = 0; // TODO: Change 
     _SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 
     _SwapChainDesc.BufferCount = 1; 
     _SwapChainDesc.OutputWindow = g_WindowHandle; 
     _SwapChainDesc.Windowed = TRUE; // TODO: Fullscreen support 
     _SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 
     _SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 

     if (FAILED(_Result = _DXGIFactory->CreateSwapChain(g_D3DDevice.Get(), &_SwapChainDesc, g_D3DSwapChain.GetAddressOf()))) 
      throw _Result; // TODO: Handle 


     if (FAILED(_Result = _DXGIFactory->MakeWindowAssociation(g_WindowHandle, DXGI_MWA_NO_ALT_ENTER))) 
      throw _Result; // TODO: Handle 


     _DXGIFactory.Reset(); 
    } 

    { 
     ComPtr<ID3D11Texture2D> _BackBuffer; 
     if (FAILED(_Result = g_D3DSwapChain->GetBuffer(0, IID_PPV_ARGS(_BackBuffer.GetAddressOf())))) 
      throw _Result; // TODO: Handle 

     if (FAILED(_Result = g_D3DDevice->CreateRenderTargetView(_BackBuffer.Get(), NULL, g_D3DRenderTargetView.GetAddressOf()))) 
      throw _Result; // TODO: Handle 
     _BackBuffer.Reset(); 


     D3D11_TEXTURE2D_DESC _Tex2DDesc = {}; 
     _Tex2DDesc.Width = 1280; // TODO: Change 
     _Tex2DDesc.Height = 720; // TODO: Change 
     _Tex2DDesc.MipLevels = 1; 
     _Tex2DDesc.ArraySize = 1; 
     _Tex2DDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
     _Tex2DDesc.SampleDesc.Count = 1; 
     _Tex2DDesc.SampleDesc.Quality = 0; 
     _Tex2DDesc.Usage = D3D11_USAGE_DEFAULT; 
     _Tex2DDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; 
     _Tex2DDesc.CPUAccessFlags = 0; 
     _Tex2DDesc.MiscFlags = 0; 

     if (FAILED(_Result = g_D3DDevice->CreateTexture2D(&_Tex2DDesc, NULL, g_D3DDepthStencil.GetAddressOf()))) 
      throw _Result; // TODO: Handle 


     D3D11_DEPTH_STENCIL_VIEW_DESC _DSVDesc = {}; 
     _DSVDesc.Format = _Tex2DDesc.Format; 
     _DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 
     _DSVDesc.Texture2D.MipSlice = 0; 
     _DSVDesc.Flags = 0; 

     if (FAILED(_Result = g_D3DDevice->CreateDepthStencilView(g_D3DDepthStencil.Get(), &_DSVDesc, g_D3DDepthStencilView.GetAddressOf()))) 
      throw _Result; // TODO: Handle 


     g_D3DDeviceContext->OMSetRenderTargets(1, g_D3DRenderTargetView.GetAddressOf(), g_D3DDepthStencilView.Get()); 

     D3D11_VIEWPORT _Viewport = { 0.0f, 0.0f, 1280.0f, 720.0f, 0.0f, 1.0f }; // TODO: Change 
     g_D3DDeviceContext->RSSetViewports(1, &_Viewport); 

    } 


    ShowWindow(g_WindowHandle, p_Show); 





    MSG _Msg = {}; 
    while (_Msg.message != WM_QUIT) 
    { 
     if (PeekMessageA(&_Msg, NULL, 0, 0, PM_REMOVE) != 0) 
     { 
      TranslateMessage(&_Msg); 
      DispatchMessageA(&_Msg); 
     } 
     else 
     { 

      g_D3DDeviceContext->ClearRenderTargetView(g_D3DRenderTargetView.Get(), DirectX::Colors::MidnightBlue); 
      g_D3DDeviceContext->ClearDepthStencilView(g_D3DDepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); 

      _Result = g_D3DSwapChain->Present(1, 0); 
      if ((_Result == DXGI_ERROR_DEVICE_REMOVED) || (_Result == DXGI_ERROR_DEVICE_RESET)) 
      { 
       // TODO: On device removed 
      } 
      else 
      { 
       if (FAILED(_Result)) 
        throw _Result; // TODO: Handle 
      } 

     } 
    } 


    g_D3DDeviceContext->ClearState(); 

    g_D3DDepthStencilView.Reset(); 
    g_D3DDepthStencil.Reset(); 
    g_D3DRenderTargetView.Reset(); 
    g_D3DSwapChain.Reset(); 

    g_WindowHandle = NULL; 

    UnregisterClassA(g_WindowClassName, p_Inst); 

    g_D3DDeviceContext.Reset(); 
    g_D3DDevice.Reset(); 

#if ALC_DEBUG 
    _D3DDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL); 
    _D3DDebug.Reset(); 
#endif 

    CoUninitialize(); 

    return (int)_Msg.wParam; 
} 


LRESULT CALLBACK WindowProc(HWND p_Window, UINT p_Msg, WPARAM p_WParam, LPARAM p_LParam) 
{ 
    PAINTSTRUCT _PaintStruct = {}; 
    HDC _DC = NULL; 

    switch (p_Msg) 
    { 
     case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
      return 0; 
     } 
     case WM_PAINT: 
     { 
      _DC = BeginPaint(p_Window, &_PaintStruct); 
      EndPaint(p_Window, &_PaintStruct); 
      return 0; 
     } 
     case WM_CLOSE: 
     { 
      // TODO: Improve this 
      if (MessageBoxA(p_Window, "Are you sure you want to quit?", "", MB_YESNO | MB_ICONQUESTION) == IDYES) 
       break; 

      return 0; 
     } 
     default: 
     { 
      break; 
     } 
    } 

    return DefWindowProcA(p_Window, p_Msg, p_WParam, p_LParam); 
} 

编辑:我想我会提到,当我关闭垂直同步(即通过数字0而不是1到现在的功能),增加内存使用率更高,速度更快。

+0

如果发生这种情况在调试更多,那么它应该没有什么可担心的。 – VTT

+0

@VTT这也发生在发布版本。我已经尝试了很多东西。编程毕竟是关于解决问题的。但是,好吧......我不能继续写更多的代码来解决这个问题。我将渲染的东西越多,我相信泄漏会更大 –

+0

您可以尝试将'#include '包装到'#if ALC_DEBUG'区块中,以便在发布版本中不会将调试内容带入范围。 – VTT

回答

1

将我的AMD Radeon R9 M375驱动程序从17.6.2更新到17.10.3修复了问题!