Sign in to follow this  
SpecialSymbols

DirectX10 Memory Leak?

Recommended Posts

I am trying to create a simple DirectX window that just draws the screen blue every frame. I followed the Microsoft tutorial, but for some reason when I create the application, it takes up 25% of my CPU and after a while causes my computer to stall. Also, the normal Windows UI features (such as the close button changing its shade of color when you mouse over it) are lagged when I run this application. I think there is a memory leak or something causing a problem in the code, but I can't seem to find it. When I run more complicated examples by MSDN or the book I am using, they don't have this problem. Here is the code, it is very simple: #include <Windows.h> #include <d3d10.h> #include <d3dx10.h> //Global Windows Variables: LPCWSTR MainClassName = L"MainWindowsClass"; HWND hWnd; HINSTANCE ThisInstance; RECT WindowRect; //Global DirectX Variables: ID3D10Device* d3dDevice = NULL; IDXGISwapChain* SwapChain = NULL; ID3D10RenderTargetView* RenderTargetView = NULL; //Global Convinience Variables: LRESULT CALLBACK MainWindowProcedure( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch (message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } bool InitializeWindows(int nCmdShow) { //STEP ONE: RegisterClass //STEP TWO: CreateWindow //STEP THREE: ShowWindow //STEP ONE WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = MainWindowProcedure; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = ThisInstance; wcex.hIcon = LoadIcon(ThisInstance, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = MainClassName; wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION); if( !RegisterClassEx(&wcex) ) return false; //STEP TWO WindowRect.left = 0; WindowRect.top = 0; WindowRect.right = 640; WindowRect.bottom = 480; AdjustWindowRect(&WindowRect, WS_OVERLAPPEDWINDOW, FALSE); hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, MainClassName, L"DirectX Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, NULL, NULL, ThisInstance, NULL); if(hWnd == NULL) { MessageBox(NULL, L"Window Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK); return false; } //STEP THREE ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return true; } bool InitializeDirectX() { //STEP ONE: Create device and swap chain //STEP TWO: Create render target view //STEP THREE: Create depth and stencil view //STEP FOUR: Set Viewport //STEP ONE DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof(sd) ); sd.BufferCount = 1; sd.BufferDesc.Width = WindowRect.right - WindowRect.left; sd.BufferDesc.Height = WindowRect.bottom - WindowRect.top; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; if( FAILED( D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL, 0, D3D10_SDK_VERSION, &sd, &SwapChain, &d3dDevice ) ) ) { return false; } //STEP TWO ID3D10Texture2D *pBackBuffer; if( FAILED( SwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID*)&pBackBuffer ) ) ) return FALSE; HRESULT hr = d3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &RenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return false; d3dDevice->OMSetRenderTargets( 1, &RenderTargetView, NULL ); //STEP THREE: empty //STEP FOUR D3D10_VIEWPORT vp; vp.Width = 640; vp.Height = 480; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; d3dDevice->RSSetViewports( 1, &vp ); return true; } void Render() { float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA d3dDevice->ClearRenderTargetView( RenderTargetView, ClearColor ); SwapChain->Present( 0, 0 ); } //Program Entry Point: int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { ThisInstance = hInstance; InitializeWindows(nCmdShow); InitializeDirectX(); //Message Loop MSG msg = {0}; while( WM_QUIT != msg.message ) { if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { Render(); } } return (int)msg.wParam; }

Share this post


Link to post
Share on other sites
Found the problem: for D3D10CreateDeviceAndSwapChain(), i had specified D3D10_DRIVER_TYPE_REFERENCE as the driver type (very slow), when I should've specified D3D10_DRIVER_TYPE_HARDWARE. For some reason, MSDN had chosen the wrong driver type in its DirectX Tutorial 1, and when I copy and pasted the code, I fell into the trap.

Share this post


Link to post
Share on other sites
So it was not caused by memory leak.

Also it is highly suggested to call

D3D10CreateDeviceAndSwapChain or
D3D10CreateDevice

this way

HRESULT hrResult = D3D10CreateDeviceAndSwapChain
...
D3D10_DRIVER_TYPE_HARDWARE,
...); or

HRESULT hrResult = D3D10CreateDevice(
...
D3D10_DRIVER_TYPE_HARDWARE,
...
);

if (hrResult == DXGI_ERROR_UNSUPPORTED
|| hrResult == E_NOINTERFACE
{
hrResult = D3D10CreateDevice(
...
D3D10_DRIVER_TYPE_WARP,
...
); or

hrResult = D3D10CreateDeviceAndSwapChain
(
...
D3D10_DRIVER_TYPE_WARP,
...
);


Error Handling;

}

Even if your app is running on a machine without a D3D10 compatible adapter, your app also can run on WARP.

http://msdn.microsoft.com/en-us/library/dd285359.aspx

[Edited by - standby01 on April 28, 2010 4:21:33 PM]

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