Can't create DirectX device on all computers

Started by
8 comments, last by Nik02 18 years ago
This is driving me crazy! :) I have a cool little game put together and I want to share it with my friends, but half of their computers don't like how I initialize directX! I'm using 9.0c Feb release, and this code works on the 4 computers I have access to, yet I have several friends (far away) that keep failing when it tries to create the D3D device. I have 5 different 'modes' I let them choose from via a text file and all 5 mode work on my laptop, but usually if one fails on a computer they all fail. What am I forgetting to check/setup to make this work on all computers with DirectX 9.0c installed and fairly recent video card?

bool InitialiseDirectX(HWND hWnd)
{	
	ifstream infile; 
	ofstream outfile;

	infile.open("DXSettings.txt");
	outfile.open("DXDebug.txt");


	// Create the D3D object
	gD3dObject=Direct3DCreate9(D3D_SDK_VERSION);

	if (gD3dObject==NULL) {
		outfile << "Failed to create Direct3D object\n";
		return FALSE;
	} else {
		outfile << "Successfully created Direct3D object\n";
	}


	D3DCAPS9 caps;
	gD3dObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);

	int vp = 0;
	if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	D3DDISPLAYMODE d3ddm;
	HRESULT hr = gD3dObject->GetAdapterDisplayMode(
                       D3DADAPTER_DEFAULT,
                       &d3ddm);
    if(FAILED(hr))
      return false;



	// Fill out some presentation parameters for running in a window
	D3DPRESENT_PARAMETERS presParams;
	ZeroMemory(&presParams,sizeof(presParams));



	char value[80];
	infile >> value; // identifier "SETTING
	infile >> value; 

	if (value[0] == '1')
	{
		presParams.Windowed	 	= TRUE;
		presParams.SwapEffect	 	= D3DSWAPEFFECT_DISCARD;
		presParams.BackBufferFormat 	= D3DFMT_UNKNOWN;
		presParams.BackBufferCount	= 1;

	} else if (value[0] == '2') {
		
		
		presParams.BackBufferWidth		  = GetSystemMetrics(SM_CXSCREEN);
		presParams.BackBufferHeight		  = GetSystemMetrics(SM_CYSCREEN);
		presParams.BackBufferFormat           = D3DFMT_A8R8G8B8;
		presParams.BackBufferCount            = 1;
		presParams.MultiSampleType            = D3DMULTISAMPLE_NONE;
		presParams.MultiSampleQuality         = 0;
		presParams.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
		presParams.hDeviceWindow              = hWnd;
		presParams.Windowed                   = FALSE;
		presParams.EnableAutoDepthStencil     = true; 
		presParams.AutoDepthStencilFormat     = D3DFMT_D24S8;
		presParams.Flags                      = 0;
		presParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
		presParams.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

	} else if (value[0] == '3') {

		presParams.BackBufferWidth            = 640;
		presParams.BackBufferHeight           = 480;
		presParams.BackBufferFormat           = D3DFMT_A8R8G8B8;
		presParams.BackBufferCount            = 1;
		presParams.MultiSampleType            = D3DMULTISAMPLE_NONE;
		presParams.MultiSampleQuality         = 0;
		presParams.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
		presParams.hDeviceWindow              = hWnd;
		presParams.Windowed                   = FALSE;
		presParams.EnableAutoDepthStencil     = true; 
		presParams.AutoDepthStencilFormat     = D3DFMT_D24S8;
		presParams.Flags                      = 0;
		presParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
		presParams.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;


	} else if (value[0] == '4') {
		
		presParams.EnableAutoDepthStencil 	= TRUE;
		presParams.BackBufferWidth        	= GetSystemMetrics(SM_CXSCREEN);
		presParams.BackBufferHeight       	= GetSystemMetrics(SM_CYSCREEN);
		presParams.FullScreen_RefreshRateInHz	= D3DPRESENT_RATE_DEFAULT; //Default Refresh Rat
	      presParams.BackBufferFormat       	= D3DFMT_X8R8G8B8;
		presParams.AutoDepthStencilFormat 	= D3DFMT_D16;
		presParams.Windowed=FALSE;
		presParams.MultiSampleType		=D3DMULTISAMPLE_NONE; //No multi-sampling
		presParams.MultiSampleQuality		=0; //No multi-sampling
		presParams.hDeviceWindow  		= hWnd;  //This is our main (and only) window
		presParams.Flags				=0;  //No flags to set
		presParams.PresentationInterval	=D3DPRESENT_INTERVAL_IMMEDIATE; //Default Presentation rate
		presParams.BackBufferCount=1;

		presParams.SwapEffect             	= D3DSWAPEFFECT_DISCARD;
		
	} else if (value[0] == '5') {
		presParams.SwapEffect              = D3DSWAPEFFECT_FLIP;
		presParams.Windowed                = FALSE;
		presParams.BackBufferFormat        = d3ddm.Format;
		presParams.BackBufferWidth         = d3ddm.Width;
		presParams.BackBufferHeight        = d3ddm.Height;
		presParams.EnableAutoDepthStencil  = TRUE;
		presParams.AutoDepthStencilFormat  = D3DFMT_D16;
		presParams.FullScreen_RefreshRateInHz      = D3DPRESENT_RATE_DEFAULT;
	}

	

 


	// Create the D3D device
	 hr = gD3dObject->CreateDevice(
		D3DADAPTER_DEFAULT, // primary adapter
		D3DDEVTYPE_HAL,         // device type
		hWnd,               // window associated with device
		vp,                 // vertex processing
	    	&presParams,             // present parameters
	    	&gD3dDevice);            // return created device

	if( FAILED(hr) )
	{
		::MessageBox(0, "CreateDevice() - FAILED, trying 16-bit depth stencil buffer", buf, 0);
		// try again using a 16-bit depth buffer
		presParams.AutoDepthStencilFormat = D3DFMT_D16;
		
		hr = gD3dObject->CreateDevice(
			D3DADAPTER_DEFAULT,
			D3DDEVTYPE_HAL,
			hWnd,
			vp,
			&presParams,
			&gD3dDevice);

		if( FAILED(hr) )
		{
	
		outfile << "Failed first attempt at creating device --- trying to render in software\n";
		// Some cards may not do hardware vertex processing so fall back to software:
		hr=gD3dObject->CreateDevice(D3DADAPTER_DEFAULT,
							D3DDEVTYPE_HAL,
							hWnd,
							D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
							&presParams, 
							&gD3dDevice);
			if (FAILED(hr))
			{
				outfile << "Failed to create device in Software ... bye\n";
				gD3dObject->Release(); // done with d3d9 object
				::MessageBox(0, "CreateDevice() - FAILED", buf, 0);
				return false;
			}
		}
	}

	gD3dObject->Release(); // done with d3d9 object

	return TRUE;
}

Advertisement
char value[80] is confusing me, and if (value[0] == '1'). It looks like its neither called or assigned anything, and thus your presentation parameters are never assigned. This would fail the device from being created. On my last random thought,

int vp = 0;

should be

DWORD vp = 0;

and thus you're working with an unsigned value. And, make sure they have the same DirectX version as yours.

I hope some of this helps!
What function fails, and what error code do you get? If it's CreateDevice(), have you tried logging your presentation parameters after the call fails to see where the issue is?
Thanks for the response.

char value[80]; is just a buffer for me to read in values from a config file. The maximum line length is 80, although for parameter I'm only reading in 1 character.


For some reason the source tag isn't showing my code right,

infile >> value; // identifier "SETTING

should be:

infile << value; // identifier "SETTING

do I have to specify anything else besides {source}{/source}? (with {} = [])

Anyways, I'm just reading in a word from my settings file, which will always be a '1', '2', '3','4', or '5'. This all works on my computer - the different blocks of code do get called and the different presentation parms are with make my screen windowed/a different resolution, etc...

Yes, CreateDevice() fails.

> have you tried logging your presentation parameters after
> the call fails to see where the issue is?

Hrmm - is there an easy way to print the whole structure to a file, or do I have to specifically send every parameter to the file?

Thanks.
Quote:Original post by syph
Hrmm - is there an easy way to print the whole structure to a file, or do I have to specifically send every parameter to the file?
Nope, you'd have to output each member unfortunately. However, there's "only" 14 of them, and you'll only be logging them once.
Ok, I've changed my code and sent it to my "testers" - we'll see what comes back.

In the mean time, are there a set of parameters that are _certain_ to succesfully create a D3Ddevice? (barring some kind of gross malfunction or misconfiguration on the client computer) I have a very simple 2D game with no effects others other than alphablending - you'd think I'd be able to pass a generic set of parameters that would work on virtually any machine with directx 9.0c installed.

Thanks again for the suggestions on debugging, steve the evil!

Unfortunately, nothing is certain. I suppose you could write a software render device, but that's just getting silly [smile]

You can use a very low end specification, however. 640x480x16 resolution, D3DSWAP_DISCARD, and one backbuffer should work on any 3D card (Even a voodoo 1).

Most cards today (GeForce 2+) will cope quite happily with 1024x768x32, 32-bit textures, trilinear texture filtering, etc etc.
Oh man, it *still* doesn't work on one friend's computer! I'm having him send me the graphics card info later today.

I just thought of something, however. I've been grabbing the current resolution and using that as my fullscreen width/length/format. Is it possible for a 3D card to support a particular resolution (and indeed be running at it), but not support that res in Fullscreen mode?

The error I'm getting is -2005530518 == Device does not support the queried technique.

Here are my presentation params:

Successfully created Direct3D objectCurrent Display Settings:Width 1280Height 1024Refresh 1Format 22Selected Setting Group 8. Trying to Create Device with the following:presParams.BackBufferWidth 1280presParams.BackBufferHeight 1024presParams.BackBufferFormat 22presParams.BackBufferCount 1presParams.MultiSampleType 0presParams.MultiSampleQuality 0presParams.SwapEffect 1presParams.hDeviceWindow 014C018CpresParams.Windowed 0presParams.EnableAutoDepthStencil 0presParams.AutoDepthStencilFormat 22presParams.Flags 0presParams.FullScreen_RefreshRateInHz 0presParams.PresentationInterval 0Failed first time - Error code is: -2005530518 //(NotAvailable -2005530518 Device does not support the queried technique.presParams.BackBufferWidth 1280presParams.BackBufferHeight 1024presParams.BackBufferFormat 22presParams.BackBufferCount 1presParams.MultiSampleType 0presParams.MultiSampleQuality 0presParams.SwapEffect 1presParams.hDeviceWindow 014C018CpresParams.Windowed 0presParams.EnableAutoDepthStencil 0presParams.AutoDepthStencilFormat 22presParams.Flags 0presParams.FullScreen_RefreshRateInHz 0presParams.PresentationInterval 0


Thanks again for the help.
Backbuffer format and auto depth stencil format cannot possibly be the same, yet in your structure they are both set to 22 (D3DFMT_X8R8G8B8). Even though you don't actually enable the auto depth stencil, some graphics drivers might fail the validation due to the format.

Niko Suni

This topic is closed to new replies.

Advertisement