Sign in to follow this  
KittensWithSpikes

cannot get rid of live objects (D3D11)

Recommended Posts

Hello I am quite new to direct X. I am current reading and going through Introduction to 3d game programming with direct x 11 

 

When finishing debugging an application I get some live objects that are still around. I have tried using the debug layer to try and tracking down where leaks are happening, but I cannot seem to find them. I am currently using WRL::ComPtr on the D3D11 interfaces. 

 

The application is the bare minimum of a D3D11 Application.

 

I have include the relevant code here.

 

D3DApp.cpp

D3DApp::~D3DApp()
{
	if (mp_immediateContext)
		mp_immediateContext->ClearState();
#if defined(REPORT_LIVE_OBJECTS)
	ComPtr<ID3D11Debug>  debug;
	mp_d3dDevice.As(&debug);
	debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);

#endif
}

void D3DApp::OnWindowResize()
{
	if (mp_renderTargetView)
		mp_renderTargetView.Get()->Release();
	if (mp_depthStencilView)
		mp_depthStencilView.Get()->Release();
	if (mp_depthStencilBuffer)
		mp_depthStencilBuffer.Get()->Release();


	mp_swapChain->ResizeBuffers(1, m_clientWidth, m_clientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0);

	ComPtr<ID3D11Texture2D> backBuffer;

	mp_swapChain->GetBuffer(0,__uuidof(ID3D11Texture2D), (void**)backBuffer.GetAddressOf());
	mp_d3dDevice->CreateRenderTargetView(backBuffer.Get(), nullptr, mp_renderTargetView.GetAddressOf());
	D3D11_TEXTURE2D_DESC desc;
	desc.Width = m_clientWidth;
	desc.Height = m_clientHeight;
	desc.ArraySize = 1;
	desc.MipLevels = 1;
	desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;

	if (m_enable4xMsaa)
	{
		desc.SampleDesc.Count = 4;
		desc.SampleDesc.Quality = m_4xmsaaQuality - 1;
	}
	else
	{
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;
	}

	desc.Usage = D3D11_USAGE_DEFAULT;
	desc.CPUAccessFlags = 0;
	desc.MiscFlags = 0;
	desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;

	HRESULT hr = mp_d3dDevice->CreateTexture2D(&desc, nullptr, mp_depthStencilBuffer.GetAddressOf());

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Failed to create a depth stencil buffer!", L"D3D ERROR", MB_OK);
		return;
	}

	hr = mp_d3dDevice->CreateDepthStencilView(mp_depthStencilBuffer.Get(), nullptr, mp_depthStencilView.GetAddressOf());

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Failed to create a depth stencil view!", L"D3D ERROR", MB_OK);
		return;
	}

	mp_immediateContext->OMSetRenderTargets(1, mp_renderTargetView.GetAddressOf(), mp_depthStencilView.Get());
	
	m_viewPort.TopLeftX = 0;
	m_viewPort.TopLeftY = 0;
	m_viewPort.MinDepth = 0.0;
	m_viewPort.MaxDepth = 1.0;
	m_viewPort.Width = static_cast<FLOAT>(m_clientWidth);
	m_viewPort.Height = static_cast<FLOAT>(m_clientHeight);

	mp_immediateContext->RSSetViewports(1, &m_viewPort);
}

bool D3DApp::InitializeD3D()
{
	UINT deviceFlags = 0;

#if defined(DEBUG) || defined(_DEBUG)

	deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;

#endif 

	D3D_FEATURE_LEVEL featureLevel;

	HRESULT hr = D3D11CreateDevice(nullptr, m_d3dDriverType, 0, deviceFlags, nullptr, 0, D3D11_SDK_VERSION, mp_d3dDevice.GetAddressOf(), &featureLevel, mp_immediateContext.GetAddressOf());

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Failed to create a D3D11 Device!", L"D3D ERROR", MB_OK);
		return false;
	}

	if (m_enable4xMsaa)
	{
		hr = mp_d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_4xmsaaQuality);

		if (FAILED(hr))
		{
			MessageBox(nullptr, L"The GPU does not support 4x MSAA", L"D3D ERROR", MB_OK);
			return false;
		}
	}

	DXGI_SWAP_CHAIN_DESC swapDesc;
	ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
	swapDesc.BufferCount = 1;
	swapDesc.BufferDesc.Width = m_clientWidth;
	swapDesc.BufferDesc.Height = m_clientHeight;
	swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	swapDesc.BufferDesc.RefreshRate.Numerator = 60;
	swapDesc.BufferDesc.RefreshRate.Denominator = 1;
	swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapDesc.OutputWindow = m_windowHandle;

	if (m_enable4xMsaa)
	{
		swapDesc.SampleDesc.Count = 4;
		swapDesc.SampleDesc.Quality = m_4xmsaaQuality - 1;
	}
	else
	{
		swapDesc.SampleDesc.Count = 1;
		swapDesc.SampleDesc.Quality = 0;
	}

	swapDesc.Windowed = true;
	swapDesc.Flags = 0;
	swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	ComPtr<IDXGIDevice> dxgiDevice = nullptr;

	hr = mp_d3dDevice.As(&dxgiDevice);

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Could not create DXGI device", L"D3D ERROR", MB_OK);
		return false;
	}

	ComPtr<IDXGIAdapter> dxgiAdapter = nullptr;
	hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)dxgiAdapter.GetAddressOf());

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Could not obtain dxgi adapter", L"D3D ERROR", MB_OK);
		return false;
	}

	ComPtr<IDXGIFactory> dxgiFactory = nullptr;

	hr = dxgiAdapter->GetParent(__uuidof(dxgiFactory), (void**)dxgiFactory.GetAddressOf());

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Could not obtain dxgi factory", L"D3D ERROR", MB_OK);
		return false;
	}

	hr = dxgiFactory->CreateSwapChain(mp_d3dDevice.Get(), &swapDesc, mp_swapChain.GetAddressOf());

	if (FAILED(hr))
	{
		MessageBox(nullptr, L"Could not create swap chain", L"D3D ERROR", MB_OK);
		return false;
	}

	OnWindowResize();

	return true;
}

D3DTestApp.cpp

void D3DTestApp::Render()
{
	float color[4] = { 0.0, 0.0, 1.0, 1.0 };
	mp_immediateContext->ClearRenderTargetView(mp_renderTargetView.Get(), color);

	mp_immediateContext->ClearDepthStencilView(mp_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

	// DRAW
	mp_swapChain->Present(0, 0);
}

and here is the warnings

D3D11 WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Producer at 0x006E4AF4, Refcount: 3. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x006EB000, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x007BA010, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296C8AC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296CD54, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296CF9C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296D334, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296D544, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296D760, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x007BCFEC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296E7FC, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296EA94, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0296FE84, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: 	Live Object at 0x0297054C, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live                         Object :     13 [ STATE_CREATION WARNING #0: UNKNOWN]
No memory leaks detected.
Visual Leak Detector is now exiting.
DXGI WARNING: Live Producer at 0x006D6780, Refcount: 4. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: 	Live Object at 0x006D8E40, Refcount: 2. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live                         Object :      1 [ STATE_CREATION WARNING #0: ]

Now one of my questions i if these live object have a ref count of 0 should they be not be cleaned up?

 

Any help or advice would be greatly appreciated.

Thank you for your time.

Share this post


Link to post
Share on other sites
Buckeye    10747

First: rather than device.As(&debug), try device->QueryInterface(IID_PPV_ARGS(&debug)) to report actual object types, rather than "Live Object." That is, you'll get descriptions in terms of "ID3D11Context" rather than "Live Object," and you can match up object addresses before exit with those reported as leaks. Much easier.

 

Second: the objects will exist (with whatever ref count) until the ComPtr actually goes out of scope - i.e., after ~D3DApp exits. So don't worry about objects with ref counts of 0.

 

EDIT: Sean Middleditch also provides good debugging techniques, which includes providing a unique name for each object, making life even easier when reporting objects.

Edited by Buckeye

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this