DirectX CreateDevice Invalid Call

Started by
4 comments, last by CountOfMonteChristo 21 years, 9 months ago
Hello. I''m relatively new to DirectX, but have been trying to learn it for a while now. Most samples and tutorials I''m compiling run fine, but now that I''m trying to make D3D app of my own, I run into an error I cannot seem to solve. The error occurs when creating the device. The CreateDevice function returns D3DERR_INVALIDCALL, and after that, the program naturally crashes. (Haven''t yet built anything robust to make in end normally, but the fact that it doesn''t work is my primary concern right now.) The VC++6 debugger pops up a messagebox which tells me the following: Unhandled Exception in d3dtest.exe: 0xC0000005: Access Violation. The debug window, by the way, tells me "First-chance exception in d3dtest.exe: 0xC0000005: Access Violation." The DirectX SDK documentation does a wonderfull job by not telling me what''s going on when you get a D3DERR_INVALIDCALL back, so I was hoping some of you could shed some light on this matter. My code is below:
  
#include <windows.h>
#include <d3d8.h>

//----------------------------------------------------------

// Globale variabelen

//----------------------------------------------------------


char g_szNaam[] = "Standaard Applicatie"; 
LPDIRECT3D8	g_pD3D = NULL;
LPDIRECT3DDEVICE8 g_pD3DDevice = NULL;
LPDIRECT3DSURFACE8 g_pD3DBackBuffer = NULL;

//----------------------------------------------------------

// MsgProc()

//----------------------------------------------------------

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;

        case WM_PAINT:
            ValidateRect( hWnd, NULL );
            return 0;
    }

    return DefWindowProc( hWnd, msg, wParam, lParam );
}
// Einde MsgProc()


//----------------------------------------------------------

// WinMain()

//----------------------------------------------------------

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = MsgProc;
	wcex.cbClsExtra=0;
	wcex.cbWndExtra=0;
	wcex.hInstance = hInstance;
	wcex.hIcon = 0;
	wcex.hCursor = 0;
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = 0;
	wcex.lpszClassName = g_szNaam;
	wcex.hIconSm = 0;

	RegisterClassEx(&wcex);
	
	HWND hWnd = CreateWindow(g_szNaam, g_szNaam,
							WS_POPUP, 
							0,0,800, 600,
							NULL,NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}
	
	g_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
	
	D3DPRESENT_PARAMETERS d3dpp;

	ZeroMemory( &d3dpp, sizeof(d3dpp) );

	d3dpp.BackBufferWidth = 800;
	d3dpp.BackBufferHeight = 600;
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
	d3dpp.BackBufferCount = 1;
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
	d3dpp.hDeviceWindow = hWnd;
	d3dpp.Windowed = FALSE;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

	HRESULT r = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice);

// Above is where the error occurs, which causes it to go to case D3DERR_INVALIDCALL in the switch statement below:


	switch(r)
	{
	case D3DERR_INVALIDCALL:
		MessageBox(hWnd, "Invalid Call", "Fout", MB_OK);
		OutputDebugString("InvalidCall\n");
		break;
	case D3DERR_NOTAVAILABLE:
		OutputDebugString("NotAvailable\n");
		break;
	case D3DERR_OUTOFVIDEOMEMORY:
		OutputDebugString("NotAvailable\n");
		break;
	default:
		OutputDebugString("Succes!");
		break;
	}

	g_pD3DDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &g_pD3DBackBuffer);
	
	ShowWindow(hWnd, nShowCmd);
	UpdateWindow(hWnd);

    MSG msg; 
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    
	UnregisterClass( g_szNaam, hInstance );

	g_pD3DBackBuffer->Release();
	g_pD3DBackBuffer = NULL;

	g_pD3DDevice->Release();
	g_pD3DDevice = NULL;

	g_pD3D->Release();
	g_pD3D = NULL;

    return TRUE;
} 
// Einde WinMain()


  
And that''s about it. If any of you can help, I''d be very grateful indeed. By the way, if you spot anything else in my code that should best be done otherwise, feel free to let me know. Thanks in advance!
Advertisement
The exception occurs because you are trying to dereference the IDirect3DDevice8 pointer after CreateDevice has failed. The pointer is probably NULL.

You should install the debug DX runtine components and then look for the resulting warning messages in the debugger when CreateDevice fails. My guess is that your display card doesn''t support the type of back buffer you are attempting to create (i.e. destination alpha).
I've looked into this a bit more, and it is indeed the case that my hardware doesn't support the display mode. I have been testing this on my notebook with an ATI Rage Mobility, where it doesn't work, and on my normal PC, which has a Geforce 3. It worked on that one.

Now that that's sorted... I'm still a bit clueless. I thought that (one of) the good thing(s) about DX was that you didn't have to take every single piece of hardware into account anymore, because DX acted as sort of an interface between the hardware (or the hardware's drivers, rather) and the application? "DirectX is an API that has direct access to your hardware, assuming that you have Windows9X/NT/2000/XP. The beauty of it is that you don't have to write separate code for each graphic card, sound card, and input device. DirectX handles the details."
Obviously, this is not the case, since you have to determine if hardware T&L is available and such, and now certain backbuffers aren't supported. I'd think that A8R8G8B8 is one of the most default types you'd get..

I realise that, if your card just doesn't support high resolutions or 32bpp, you're stuck. But at 800x600? Windows runs at 800x600x32 on that machine.. Most of the samples run fine. So why shouldn't it work all of a sudden?

[edited by - Bas Paap on July 18, 2002 7:39:31 PM]
quote:Original post by Bas Paap
Obviously, this is not the case, since you have to determine if hardware T&L is available and such, and now certain backbuffers aren't supported.

unfortunately, you need to enumerate available display modes and depth/stencil formats, as well as available multisample types, on application startup. you can find some code in d3dapp.cpp.
quote:
I'd think that A8R8G8B8 is one of the most default types you'd get..

actually, alpha in backbuffer is very rare. X8R8G8B8 should be much more common. but you better do the enumeration if you want your program to work on computers other than yours.

edit: forgot to tell you to use the debug runtime, you will find it very helpful.

---
Come to #directxdev IRC channel on AfterNET

[edited by - niyaw on July 18, 2002 7:47:19 PM]
quote:
unfortunately, you need to enumerate available display modes and depth/stencil formats, as well as available multisample types, on application startup. you can find some code in d3dapp.cpp.


Hmm, that''s too bad. But thanks for the advice! I''ll look into that right away.

quote:
actually, alpha in backbuffer is very rare. X8R8G8B8 should be much more common.


Really? That''s odd. I''d think that Alpha blending is a rather common technique. It''s used just about anywhere, after all... Is it not possible at all to let DX perform Alpha Blending then, if it''s not supported in the backbuffer?

quote:
edit: forgot to tell you to use the debug runtime, you will find it very helpful.


Yup, I''m indeed using it right now. It''s very helpful indeed. Thanks for all the good advice!
quote:Original post by Bas Paap
I''d think that Alpha blending is a rather common technique. It''s used just about anywhere, after all... Is it not possible at all to let DX perform Alpha Blending then, if it''s not supported in the backbuffer?

only if you''re using DESTALPHA blending states do you need alpha channel in target. most alphablending configs, such as SRCALPHA/INVSRCALPHA, don''t need alpha channel in the destination, and thus work fine with no-alpha backbuffers.

---
Come to #directxdev IRC channel on AfterNET

This topic is closed to new replies.

Advertisement