LPDIRECT3DDEVICE9->CreateDevice(...) is failing

Pages: 12
Oct 30, 2013 at 11:30pm
Okay so I've been following Direct3D tutorials from Chad Vernon and I've gone past the part where he's creating his own OOP framework for it.
I've taken all of this and sort of dumbed it down a bit (or complicated it more XD) but I have a problem as the CreateDevice(...) always fails in runtime (and error messages build in catch this for me)

Common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once

#define RELEASE(x) x->Release(); x = NULL;
#define STRINGIFY(x) #x
#define ST(x) STRINGIFY(x)
#define CONCAT(x, y) x##y
#define CAT(x, y) CONCAT(x, y)
#define MSG_ERR(x, file, line) CAT(x, CAT(CAT("\n\nFile: ", file), CAT("\nLine: ", ST(line))))

#define SS_FULLSCREEN (WS_EX_TOPMOST| WS_POPUP)
#define SS_FIXEDSCREEN (WS_OVERLAPPED | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU)
#define SS_BORDERLESS WS_OVERLAPPED
#define SS_WINDOWED WS_OVERLAPPEDWINDOW 



Core_Direct3D.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//receives Common.h
//receives d3d9.h and d3dx9.h (and anything else needed through its header)
bool SB::Core::Direct3D::Initialise(HWND hWnd, bool windowed){
	Windowed = windowed;
	m_hWnd = hWnd;
	if(p_DX)
		RELEASE(p_DX);
	if(p_Device)
		RELEASE(p_Device);
	p_DX = Direct3DCreate9(D3D_SDK_VERSION);
	if(!p_DX){
		MessageBox(NULL, MSG_ERR("Failed: Direct3DCreate9()", __FILE__, __LINE__), "Critical Error!", MB_ICONERROR | MB_OK);
		return false;
	}
	p_DX->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &m_displayMode);
	p_DX->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_caps);
	DWORD vertexProcessing = 0;
	if(m_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){
		vertexProcessing = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
		if(m_caps.DevCaps & D3DDEVCAPS_PUREDEVICE)
			vertexProcessing |= D3DCREATE_PUREDEVICE;
	}
	else
		vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	if(!BuildPresentParameters()){
		p_DX->Release();
		p_DX = NULL;
		return false;
	}
	HRESULT hresult = 0;
	//Create the device
	hresult = p_DX->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, vertexProcessing, &m_PP, &p_Device);
	if(FAILED(hresult)){
		p_DX->Release();
		p_DX = NULL;
		MessageBox(NULL, MSG_ERR("Failed: CreateDevice()", __FILE__, __LINE__), "Critical Error!", MB_ICONERROR | MB_OK);
		return false;
	}
	return true;
}



Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	WNDCLASSEX wc;
	ZeroMemory(&wc, sizeof(wc));

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = (CS_HREDRAW | CS_VREDRAW | CS_OWNDC);
	wc.lpfnWndProc = WinProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	//wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CUNIT));
	//wc.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CUNIT));
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszMenuName = NULL;
	wc.hbrBackground = (HBRUSH)BLACK_BRUSH;//COLOR_WINDOW;
	wc.lpszClassName = WINDOW_TITLE;
	RegisterClassEx(&wc);

	HWND hWnd = CreateWindow(WINDOW_TITLE, WINDOW_TITLE, SCREEN_STYLE, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_W, SCREEN_H, NULL, NULL, hInstance, NULL);
	if(!hWnd){
		MessageBox(NULL, MSG_ERR("Failed: CreateWindow()", __FILE__, __LINE__ -2), "Critical Error!", MB_ICONERROR | MB_OK);
		return 0;
	}
	{//Use rect as a temp value
		RECT rect = {0, 0, SCREEN_W, SCREEN_H};
		AdjustWindowRect(&rect, GetWindowLong(hWnd, GWL_STYLE), false);
		SetWindowPos(hWnd, 0, 0, 0, rect.right-rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE);
	}
	ShowWindow(hWnd, nCmdShow);

	UpdateWindow(hWnd);
	SB::Core::Engine::Setup(hWnd, !FULLSCREEN);

	MSG msg;
	double seconds;
	while(true){
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
			if(msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else if(p_D3D->getDevice()){
			seconds = targetFrames(FRAME_TARGET);
			SB::Core::Engine::TickGame(seconds);
			SB::Core::Engine::Render();
		}
	}
	return 0;
}

LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch(msg){
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		ValidateRect(hWnd, 0);
		return 0;
	case WM_SIZE:
		if(wParam == SIZE_MINIMIZED)
			SB::Core::Engine::active = false;
		else{
			SB::Core::Engine::active = true;
			SCREEN_W = LOWORD(lParam);
			SCREEN_H = HIWORD(lParam);
			if(SB::Core::Engine::D3D.getDevice())
				SB::Core::Engine::D3D.Reset();
		}
        //Other cases and defaults and stuffs
        }
    return 0; //(Actually returns the Def_shiz(...)
}


The only thing I know for certain is that for some reason CreateDevice() is returning <0 (I will try and get the value returned and will post incase it's of any help).
Last edited on Nov 5, 2013 at 3:24pm
Oct 31, 2013 at 12:26am
Okays... I've found out that the value returned by CreateDevice() is always
-2005530516

Although I still have no idea what this means
Last edited on Oct 31, 2013 at 12:38am
Oct 31, 2013 at 3:33am
If the
CreateDevice()
method succeeds, then the return value is D3D_OK.

I would suggest that, in your Core_Direct3D.cpp file, change the
FAILED()
macro on line 33 around a bit. Try comparing the
hresult
with the following error codes to narrow down your problem.

1
2
3
4
5
6
7
8
9
if(hresult == D3DERR_DEVICELOST) {
	/**/
}else if(hresult == D3DERR_INVALIDCALL) {
	/**/
}else if(hresult == D3DERR_NOTAVAILABLE) {
	/**/
}else if(hresult == D3DERR_OUTOFVIDEOMEMORY) {
	/**/
}


*EDIT* Googling:
direct3d createdevice "-2005530516"
brings up a lot of results. Try your luck there.
Last edited on Oct 31, 2013 at 3:40am
Oct 31, 2013 at 9:50am
Okay, I will update my result as soon as I can... I just noticed that my code doesn't actually show how the Initialise function is called... It's called from SB::Core::Engine::Setup along with some prerequisites and safety procedures.
That's just to clarify.
Oct 31, 2013 at 9:57am
That error it means D3DERR_INVALIDCALL.
Nov 1, 2013 at 10:52am
Okays, thanks for finding that one out before I had chance to...
So any ideas how I rectify this? (And yeah I'm just gonna take a look down MSDN now that I have that code)

EDIT: I can't find anything relevant to my situation so far, lots of people say they get this error when forgetting to initialise the D3DPRESENT_PARAMETERS but this is done in my BuildPresentParameters(), and it is checked to make sure it's successful...

I've tried running my little app in debug mode and got the following response:
First-chance exception at 0x00F75046 in MAIN.exe: 0xC0000005: Access violation reading location 0x00000188.

If there is a handler for this exception, the program may be safely continued.


So I'm imagining there's nothing wrong with the actual Direct3D aspect of this programming, just my careless placement of members..?
Last edited on Nov 1, 2013 at 11:30am
Nov 1, 2013 at 11:41am
Does the debug only show one error at a time until something is fixed because this is the only error I can see and it's got pretty much nothing to do with CreateDevice().

My error comes from here:
1
2
3
SB::Core::Direct3D::getDevice(){
    return p_Device; //Error here!
}


But the catch what I've put in my program is getting CreateDevice() as failing, nothing to do with the getDevice().

I usually don't try and ask much and I try figure it out myself but I'm really confused here
Last edited on Nov 1, 2013 at 11:49am
Nov 1, 2013 at 5:25pm
I don't think it's the cause of your problem, but don't use macros (#define) if you don't know what you're doing.

You have:
#define RELEASE(x) x->Release(); x = NULL;

used like:
1
2
	if(p_DX)
		RELEASE(p_DX);


results in the following expansion:
1
2
3
	if(p_DX)
		p_DX->Release();
	p_DX = NULL;

which is harmless for that particular use case, but it isn't what one expects and could be problematic elsewhere.

An inline function would probably be more appropriate in C++.
Nov 1, 2013 at 10:51pm
Oh indeed, thanks for that... Wonder if somewhere this is setting something to null that is needed in the create device?
Nov 1, 2013 at 11:02pm
I noticed something, might be nothing.

D3DERR_INVALIDCALL : The method call is invalid. For example, a method's parameter may not be a valid pointer.

HRESULT CreateDevice(
  [in]           UINT Adapter,
  [in]           D3DDEVTYPE DeviceType,
  [in]           HWND hFocusWindow,
  [in]           DWORD BehaviorFlags,
  [in, out]      D3DPRESENT_PARAMETERS *pPresentationParameters,
  [out, retval]  IDirect3DDevice9 **ppReturnedDeviceInterface
);


What exactly is p_Device?
Nov 2, 2013 at 12:28pm
Yeah, I thought about that but I have checked everything to do with p_Device, and the m_PP, I have a feeling that the RELEASE macro may be clearing the settings so I need to check that out, p_Device is a pointer to a DIRECT3DDEVICE9 (set to NULL) will point to the device by CreateDevice().

And the D3DPRESENT_PARAMERTERS called m_DD is initialised in BuildPresentParamerters...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bool SB::Core::Direct3D::BuildPresentParameters(){
	ZeroMemory(&m_PP, sizeof(m_PP));
	D3DFORMAT adapterFormat = (Windowed) ? m_displayMode.Format : D3DFMT_X8R8G8B8;
	if(SUCCEEDED(p_DX->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8)))
		m_PP.AutoDepthStencilFormat = D3DFMT_D24S8;
	else if(SUCCEEDED(p_DX->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8)))
		m_PP.AutoDepthStencilFormat = D3DFMT_D24X8;
	else if(SUCCEEDED(p_DX->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16)))
		m_PP.AutoDepthStencilFormat = D3DFMT_D16;
	else{
		MessageBox(NULL, MSG_ERR("Invalid Depth Format", __FILE__, __LINE__), "Critical Error!", MB_ICONERROR | MB_OK);
		return false;
	}
	m_PP.BackBufferWidth = (Windowed) ? 0 : m_displayMode.Width;
	m_PP.BackBufferHeight = (Windowed) ? 0 : m_displayMode.Height;
	m_PP.BackBufferFormat = adapterFormat;
	m_PP.BackBufferCount = 1;
	m_PP.MultiSampleType = D3DMULTISAMPLE_NONE;
	m_PP.MultiSampleQuality = 0;
	m_PP.SwapEffect = D3DSWAPEFFECT_DISCARD;
	m_PP.hDeviceWindow = m_hWnd;
	m_PP.Windowed = Windowed;
	m_PP.EnableAutoDepthStencil = true;
	m_PP.FullScreen_RefreshRateInHz = (Windowed) ? 0 : m_displayMode.RefreshRate;
	m_PP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	return true;
}
Nov 2, 2013 at 10:09pm
Is it a pointer to a DIRECT3DDEVICE9, in other words

DIRECT3DDEVICE9* device = NULL;

or

DIRECT3DDEVICE9 device = NULL;

Because it smells like an already-typedef'd pointer to something else.

EDIT* You mean m_PP, not m_DD?

EDIT AGAIN* Incase you haven't seen this already, here's a snippet from MSDN describing the D3DPRESENT_PARAMETERS structure which might be of interest:

MultiSampleQuality
Type: DWORD
Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by CheckDeviceMultiSampleType. Passing a larger value returns the error D3DERR_INVALIDCALL. Paired values of render targets or of depth stencil surfaces and D3DMULTISAMPLE_TYPE must match.
Last edited on Nov 2, 2013 at 10:20pm
Nov 4, 2013 at 9:00am
Yea I did mean m_PP sorry, and also it says the valid range is between zero and its max... The value I've set is just zero, I expect it means inclusively?

By the way I double checked the value returned by CreateDevice and it is definitely D3DERR_INVALIDCALL, I still can't figure out why though, all my variables are initialised and any pointer/references are to valid candidates.

And LPDIRECT3DDEVICE9 is defined as IDirect3DDevice9*
CreateWindow() needs an IDirect3DDevice9** which is used via reference.
Last edited on Nov 5, 2013 at 7:01pm
Nov 5, 2013 at 3:25pm
*Nudge*
:(
Nov 5, 2013 at 9:50pm
This is tricky business, see.
I'll give this one more galant research effort, but I really have no clue.
Nov 5, 2013 at 9:57pm
Thank you very much for the attempted help, I shall upload all my relevant code files into a dropbox folder shortly if you could wait for that. This is isolated from the rest of the project so it's not too large to filter through but I've been through the source code countless times myself and still can't find the problem.
Nov 5, 2013 at 10:22pm
Sure, I'll be monitoring this thread.
Nov 5, 2013 at 10:43pm
Hey, I managed to find my direct3d settings and switch it to debug mode rather than release... Now running the F5 debug on visual studio I get this message:
[output]Invalid BehaviourFlags parameter. ValidateCreateDevice failed.[output]

This is the value called vertexProcessing, now I just need to find out what is wrong with it!

Outputting the value allows me to see that vertexProcessing is setup for a hardware and pure device, which I don't think my machine is capable of but it's definitely present in dev caps.
Last edited on Nov 5, 2013 at 11:10pm
Nov 5, 2013 at 11:12pm
You could try explicitly setting vertexProcessing in core_direct3d.cpp to one of the following values, just to see what happens:

D3DCREATE_SOFTWARE_VERTEXPROCESSING
D3DCREATE_HARDWARE_VERTEXPROCESSING
D3DCREATE_MIXED_VERTEXPROCESSING


*EDIT* I did some snooping, and maybe it's because your graphic card is outdated(?)

1.)Run > dxDiag.exe

2.)Select Display tab

3.)What does it say under Drivers>DDI version?
Last edited on Nov 5, 2013 at 11:39pm
Nov 6, 2013 at 8:11am
I don't even have a graphics card which is why I was expecting it to return as software processing (I have a laptop with an Intel chipset)
I also tried explicitly declaring the hardware processing but it ONLY works on its own, if pure device or the transform and light is also added then create device still fails.

I'm just worried incase I need these properties in future (although I have no idea what they do cos I've forgot)

EDIT: I don't believe this is of any use now since I've found the source of the problem but since I said I'd upload it, here is my project.
https://www.dropbox.com/sh/6y8pq0lkkrsn3au/Hl3Rise83v
Last edited on Nov 6, 2013 at 9:55am
Pages: 12