Sign in to follow this  
syph

Can't create DirectX device on all computers

Recommended Posts

syph    140
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;
}

Share this post


Link to post
Share on other sites
nullsmind    100
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!

Share this post


Link to post
Share on other sites
Evil Steve    2017
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?

Share this post


Link to post
Share on other sites
syph    140
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...

Share this post


Link to post
Share on other sites
syph    140
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.

Share this post


Link to post
Share on other sites
Evil Steve    2017
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.

Share this post


Link to post
Share on other sites
syph    140
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!

Share this post


Link to post
Share on other sites
Evil Steve    2017
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.

Share this post


Link to post
Share on other sites
syph    140
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 object
Current Display Settings:
Width 1280
Height 1024
Refresh 1
Format 22
Selected Setting Group 8. Trying to Create Device with the following:
presParams.BackBufferWidth 1280
presParams.BackBufferHeight 1024
presParams.BackBufferFormat 22
presParams.BackBufferCount 1
presParams.MultiSampleType 0
presParams.MultiSampleQuality 0
presParams.SwapEffect 1
presParams.hDeviceWindow 014C018C
presParams.Windowed 0
presParams.EnableAutoDepthStencil 0
presParams.AutoDepthStencilFormat 22
presParams.Flags 0
presParams.FullScreen_RefreshRateInHz 0
presParams.PresentationInterval 0

Failed first time - Error code is: -2005530518

//(NotAvailable -2005530518 Device does not support the queried technique.

presParams.BackBufferWidth 1280
presParams.BackBufferHeight 1024
presParams.BackBufferFormat 22
presParams.BackBufferCount 1
presParams.MultiSampleType 0
presParams.MultiSampleQuality 0
presParams.SwapEffect 1
presParams.hDeviceWindow 014C018C
presParams.Windowed 0
presParams.EnableAutoDepthStencil 0
presParams.AutoDepthStencilFormat 22
presParams.Flags 0
presParams.FullScreen_RefreshRateInHz 0
presParams.PresentationInterval 0



Thanks again for the help.

Share this post


Link to post
Share on other sites
Nik02    4348
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.

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