0
$\begingroup$

This one I am not getting even one bit.

I started learning directx11 and using the basic dx initialization i tried a experiment by allowing an option to destroy the window and creating it again initializing direct x again(any key press triggers it).

but i observe during debugging(also by opening task manager) that memory occupied by dx com objects are not getting released,memory keeps adding up as a new window is created.

#include"windowcreation.h"

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3d10.lib")
#pragma comment(lib,"D3dcompiler.lib")

#include<d3d11_1.h>
#include<d3d10.h>
#include <D3Dcompiler.h> 
#include<DirectXMath.h>
#include<DirectXColors.h>


#include<stdio.h>
#include <io.h>
#include <fcntl.h>
#include<iostream>
#include<fstream>



bool openglinuse = false;
bool switchRenderDrivers = false;
bool switchrendercomsumequitmessage = false;
bool running = true;

//--------------------------------------------DX Globals--------------------------------------------
DXWindow window(1920, 1080, "dxandgl");

//dx data
struct dxData
{
    IDXGISwapChain* SwapChain;
    ID3D11Device* d3d11Device;
    ID3D11DeviceContext* d3d11DevCon;
    ID3D11RenderTargetView* renderTargetView;
};

dxData* dxessentials;


std::ofstream fileone("logs.txt");



//---------------------------------------------functions------------------------------------------------
bool initdirectx(HINSTANCE hinst);
bool init();
void render();
void update(double);
void destroy();
int messageloop(HINSTANCE);

bool initdirectx(HINSTANCE hinst)
{
    HRESULT hr;

    dxessentials = new dxData();

    //Describe our Buffer
    DXGI_MODE_DESC bufferDesc;

    ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

    bufferDesc.Width = window.getWidth();
    bufferDesc.Height = window.getHeight();
    bufferDesc.RefreshRate.Numerator = 60;
    bufferDesc.RefreshRate.Denominator = 1;
    bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    //Describe our SwapChain
    DXGI_SWAP_CHAIN_DESC swapChainDesc;

    ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

    swapChainDesc.BufferDesc = bufferDesc;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.BufferCount = 2;
    swapChainDesc.OutputWindow = window.getWindowHandle();
    swapChainDesc.Windowed = TRUE;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;


    //Create our SwapChain
    hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &(dxessentials->SwapChain), &(dxessentials->d3d11Device), NULL, &(dxessentials->d3d11DevCon));

    //Create our BackBuffer
    ID3D11Texture2D* BackBuffer;
    hr = dxessentials->SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);

    //Create our Render Target
    hr = dxessentials->d3d11Device->CreateRenderTargetView(BackBuffer, NULL, &(dxessentials->renderTargetView));
    BackBuffer->Release();

    //Set our Render Target
    dxessentials->d3d11DevCon->OMSetRenderTargets(1, &(dxessentials->renderTargetView), NULL);

    return true;
}

int messageloop(HINSTANCE hinst)
{
    MSG message;
    ZeroMemory(&message, sizeof(MSG));

    while (true)
    {
        if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
        {
            if (message.message == WM_QUIT)
                break;
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
        else
        {
            update(0.0);
            render();
        }
    }

    return (int)message.wParam;
}


bool init()
{


    return true;
}


void update(double delta)
{


}

void render()
{
    //Clear our backbuffer to the updated color
    const float bgColor[] = { 0.0,0.0,0.0, 1.0f };

    dxessentials->d3d11DevCon->ClearRenderTargetView(dxessentials->renderTargetView, bgColor);

    dxessentials->SwapChain->Present(0, 0);
}

void destroy()
{
    dxessentials->d3d11DevCon->OMSetRenderTargets(0,NULL, NULL);
    dxessentials->d3d11DevCon->Flush();
    fileone << '\n' << dxessentials->renderTargetView->Release();
    fileone << '\n' << dxessentials->d3d11DevCon->Release();
    fileone << '\n' << dxessentials->SwapChain->Release();
    fileone << '\n' << dxessentials->d3d11Device->Release();

    delete dxessentials;
    dxessentials = nullptr;
}


int WINAPI WinMain(HINSTANCE hinst, HINSTANCE previnst, LPSTR cmdparams, int showcmd)
{
    window.registerWindow(hinst);

    while(running)
    {
        //DX code

            fileone << "DX \n";
            fileone.flush();
            if (!window.initializeWindow(hinst, showcmd, true, "DX101"))
            {
                MessageBox(0, "Window Initialization - Failed", "Error", MB_OK);
                return 0;
            }

            if (!initdirectx(hinst))
            {
                MessageBox(0, "direct x Initialization - Failed", "Error", MB_OK);
                return 0;
            }


            if (!init())
            {
                MessageBox(0, "Scene Initialization - Failed", "Error", MB_OK);
                return 0;
            }


        messageloop(hinst);
        destroy();

    }


    fileone << "\nGoing out\n";
    fileone.flush();
    fileone.close();

    return 0;


}



LRESULT CALLBACK windowprocedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)    //Check message
    {

    case WM_KEYDOWN:    //For a key down
                        //if escape key was pressed, display popup box
        if (wParam == VK_ESCAPE) {
            if (MessageBox(0, "Are you sure you want to exit?",
                "Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)

                //Release the windows allocated memory  
                DestroyWindow(hwnd);
        }
        else
        {
            switchrendercomsumequitmessage = true;
            DestroyWindow(hwnd);
        }
        return 0;

    case WM_SIZE:
        return 0;

    case WM_NCDESTROY:    //if x button in top right was pressed
        if (switchrendercomsumequitmessage)
            switchrendercomsumequitmessage = false;
        else
            running = false;

        PostQuitMessage(0);
        return 0;
    }
    //return the message for windows to handle it
    return DefWindowProc(hwnd,
        msg,
        wParam,
        lParam);
}

I tried the following-

  1. tried doing the same with out dx initialization and it was fine no memory leak.So I guess problem is with dx coms.

  2. I am sure i am releasing the coms as the output log shows zero references for each object i release.

So could any one explain me what is going wrong and how the memory is leaking. Also a possible fix if any.

$\endgroup$
5
  • $\begingroup$ windows has a comptr class for managing the handles $\endgroup$ Nov 30, 2017 at 16:23
  • $\begingroup$ using comptr gives same problem.No idea why. $\endgroup$
    – VersesDev
    Nov 30, 2017 at 17:11
  • $\begingroup$ Does the amount of "leaked memory" grow each time you do this or only the first? if only the first it might be something like, even though you released an object (ref count decriment) it's deciding to keep it around until your app closes or something. $\endgroup$
    – Alan Wolfe
    Dec 2, 2017 at 16:03
  • $\begingroup$ Each time that too the same amount by which it was started $\endgroup$
    – VersesDev
    Dec 2, 2017 at 16:10
  • $\begingroup$ Around 18 mb to be exact $\endgroup$
    – VersesDev
    Dec 2, 2017 at 16:10

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.