2017-11-11 7 views
1

나는 Direct3D를 좀 배우고 있으며,이 아주 기본적인 코드를 가지고있다. 너무 멋진 것은 아니다. Visual Studio에서 디버깅하는 동안 나는 constantly increasing memory usage을 발견했습니다. 다소 이상합니다.IDXGISwapChain :: 현재 메모리 누수

내가 관찰 한 바에 따르면 IDXGISwapChain::Present은 각 프레임 업데이트마다 새 메모리 블록을 할당합니다. Here is a difference between two memory snapshots, 약 7 초 차이.

내가이 문제의 원인이 될지 모르겠다. 어쩌면 정리 기능을 호출하는 것을 잊어 버린 것일까? 그리고 저는 버퍼 나 쉐이더 나 그런 것들을 가지고 있지도 않습니다. 이 문제를 어떻게 해결할 수 있는지 정말 알고 싶습니다.

//============================================================================== 
// 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 Release 빌드에서도 발생합니다. 나는 이미 많은 것을 직접 시도했다. 프로그래밍은 결국 문제를 해결하는 데 있습니다. 하지만 글쎄 ... 나는 그런 문제로 더 많은 코드를 작성하는 것을 계속할 수 없다. 더 많은 것들을 렌더링 할 것이고, 누설이 더 커질 것이라 확신합니다. –

+0

'#include '을'#if ALC_DEBUG' 블록으로 래핑 해 볼 수 있습니다. 그래서 릴리즈 빌드에서 디버그 항목을 가져 오지 않을 것입니다. – VTT

답변

1

AMD Radeon R9 M375 드라이버를 17.6.2에서 17.10.3으로 업데이트하면 문제가 해결되었습니다!