Skip to main content
GameDev.net gamedev.net
🔒 Locked

CreateDevice fails

Started by prux Dec 17, 2007 at 2:24 PM 15 replies 4.1k views
Original Post
prux
prux
Hey, very strange error here because it used to be work. I would create the Direct3D8 interface: D3DInit.Windowed = false; D3DInit.Backbufferwidth = 320; D3DInit.Backbufferheight = 200; D3DInit.Backbuffercount = 1; D3DInit.Backbufferformat = D3DFMT_X8R8G8B8; D3DInit.SwapEffect = D3DSWAPEFFECT_DISCARD; D3DInit.hDeviceWindow = HWindow; everything else is zero. Direct3D.CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, HWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DInit, Device); and it drops INVALIDCALL error. It does that when I changed to D3DDEVTYPE_REF and D3DCREATE_SOFTWARE_VERTEXPROCESSING the flags. What isnt good?
Evil Steve
Evil Steve
Quote:
Original post by prux
What isnt good?
What do the Debug runtimes tell you isn't good?

Start menu -> Programs -> DirectX SDK -> Utilities -> DirectX Control Panel (Or DirectX Control Panel in the Windows control panel for older SDKs), go to the Direct3D 9 tab and make sure "Use Debug Version of Direct3D 9" is set. Then D3D will give you meaningful, helpful error messages in the debug output window when something goes wrong.
J-Fox
J-Fox
This works for me:

D3DInit.Windowed = false;
D3DInit.Backbufferwidth = 320;
D3DInit.Backbufferheight = 240;
D3DInit.Backbuffercount = 1;
D3DInit.Backbufferformat = D3DFMT_X8R8G8B8;
D3DInit.SwapEffect = D3DSWAPEFFECT_DISCARD;
D3DInit.hDeviceWindow = HWindow;

320x200 is not supported by my monitor

//Edit: oh I seem to have skipped one line when reading for the first time and mixed up depthstencil and backbufferformat *woops - fixed*...

Direct3D.CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, HWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DInit, Device);

doesnt work for me either


Direct3D.CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, HWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DInit, Device);

works though
jollyjeffers
jollyjeffers
Code around the CreateDevice() call is very dependent on the capabilities of the hardware you're trying to create a device for.

ENUMERATE, ENUMERATE, ENUMERATE [wink]

You need to be making calls to pretty much every function listed on this doc page BEFORE calling CreateDevice(). There are relatively few things that you can actually assume are supported by hardware.

If you're confused about the usage of those functions, run a search on them in the DXUT framework. It'll be cryptic, but you can find examples on how to call and use their results.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
prux
prux
Thanx the answer, but this isnt the sollution. First, it works with no windowed or fullscreen mode and no matter which resultion/color format I give. Games works with "almost" all formats and its not an old card.
Evil Steve
Evil Steve
Quote:
Original post by prux
Thanx the answer, but this isnt the sollution. First, it works with no windowed or fullscreen mode and no matter which resultion/color format I give. Games works with "almost" all formats and its not an old card.
Well, what formats does enumeration tell you are available?

EDIT: This might be a silly question, but you do have the DirectX 8 SDK installed, right? Otherwise the reference rasterizer won't be available. What does the DX caps viewer (In Start Menu -> DirectX SDK -> Utilities -> DirectX Caps Viewer) say? Does it show "Reference" as well as "HAL" under your video card type?
jollyjeffers
jollyjeffers
Quote:
Original post by prux
Thanx the answer, but this isnt the sollution
I'm sorry, but it is quite absolutely the solution. If you've found a magic combination of values that work then you got lucky, nothing more.

An D3DERR_INVALIDCALL error is telling you that the values you pass in are incorrect. Enumeration is the intended route for which you should at the very least validate and ideally discover your parameters.

If you implement enumeration code correctly you will quickly find which value (or combination of values) are incorrect. Now that won't make it work, but it will give you some cold hard evidence as to why you're getting your error, and you can work it through from there...

Would you write code without *any* error checking? Or do you just write 1000's of lines of code and just cross your fingers and hope it doesn't crash and burn? Enumeration is just preemptive error checking.

hth
Jack
<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
prux
prux
Do you guys want to laugh? Ive just downloaded and installed the SDK (www.microsoft.com/directx) and I cant see any DirectX icon at control panel...
sirob
sirob
Quote:
Original post by prux
Do you guys want to laugh? Ive just downloaded and installed the SDK (www.microsoft.com/directx) and I cant see any DirectX icon at control panel...

That's because it doesn't put the icon in the control panel. It places it in the start menu, under Start -> Programs -> DirectX SDK -> Utilities -> DirectX Control Panel.
Sirob Yes.» - status: Work-O-Rama.
prux
prux
Ok :) then only one question's left: where is the "debug output window"? I set the debugs on
prux
prux
hm I see this "debug windows" comes automatically when testing some sample stuff. But my program is written under delphi. Maybe they cannot be debugged? It says the program excited unexpectedly while PIX was analyzing.
Evil Steve
Evil Steve
Quote:
Original post by prux
Ok :) then only one question's left: where is the "debug output window"? I set the debugs on
Link
prux
prux
Okay Ive done some radical changes in my program. First, it used DirectX8, now I changed to 9.

Now the 2nd form (D3DDEVTYPE_REF and D3DCREATE_SOFTWARE_VERTEXPROCESSING) works. Its interesting, because the first form used to work. And now I can debug my app (It looks like Delphi's problem). I got this:

Frame 000001 ........PRE: IDirect3D9::GetAdapterDisplayMode(0, 0x0409260B)
Frame 000001 ........POST: IDirect3D9::GetAdapterDisplayMode(0, 0x0409260B)
Frame 000001 ........PRE: IDirect3D9::CreateDevice(0, D3DDEVTYPE_HAL, 0x000F02A6, 0x00000040, 0x040AF368, 0x004B8C50)
Direct3D9: (WARN) :HW device not available. GetAdapterCaps fails.
Frame 000001 ........POST: IDirect3D9::CreateDevice(0, D3DDEVTYPE_HAL, 0x000F02A6, 0x00000040, 0x040AF368, 0x004B8C50)
Frame 000001 ........PRE: IDirect3D9::CreateDevice(0, D3DDEVTYPE_REF, 0x000F02A6, 0x00000020, 0x040AF368, 0x004B8C50)
Evil Steve
Evil Steve
Quote:
Original post by prux
Direct3D9: (WARN) :HW device not available. GetAdapterCaps fails.
That means D3D can't see any 3D hardware. I've only ever seen that wehn trying to use D3D through remote desktop. Do you have the latest drivers?
Also, what output do you get after that? There should be something saying why CreateDevice() failed.
prux
prux
Quote:
Also, what output do you get after that? There should be something saying why CreateDevice() failed.


oh I didnt clear it up enough... I hate two CreateDevice calling. When I call CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window, D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DInit, Device);

it drops fails both with D8 and D9. So, it says no HW (Frame 000001 ........PRE: IDirect3D9::CreateDevice(0, D3DDEVTYPE_HAL, 0x000F02A6, 0x00000040, 0x040AF368, 0x004B8C50)
Direct3D9: (WARN) :HW device not available. GetAdapterCaps fails.)

but my program watch its result and when its not OK it tries to create the software device:

CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, Window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DInit, Device);

it also drops INVALIDCALL at D8 but works on D9!!

But lets see a modified version under D8 (its delphi but easy for C programmers too :)

 Direct3D:= Direct3DCreate8 (D3D_SDK_VERSION);// infó FillChar (VideoCardInfo, SizeOf(VideoCardInfo), 0); Res:= Direct3D.GetAdapterDisplayMode (D3DADAPTER_DEFAULT, VideoCardInfo); // OK!!!!!// caps FillChar (Caps, SizeOf(Caps), 0); Res:= Direct3D.GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Caps); if Res = 0 then        begin         DEVT:= D3DDEVTYPE_HAL        end        else             begin              Res:= Direct3D.GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, Caps);              if Res = 0 then DEVT:= D3DDEVTYPE_REF;             end; // FIRST ERROR: D3DDEVTYPE_HAL not available! But prog works if Caps.VertexProcessingCaps <> 0 then Flag:= D3DCREATE_HARDWARE_VERTEXPROCESSING else Flag:= D3DCREATE_SOFTWARE_VERTEXPROCESSING; // VertexProcessingCaps says 123 hence there IS D3DCREATE_HARDWARE_VERTEXPROCESSING FillChar (D3DInit, SizeOf(D3DInit), 0); WITH D3DInit DO BEGIN  Windowed:= TRUE;  BackBufferCount:= 1;  BackBufferFormat:= VideoCardInfo.Format;  SwapEffect:= D3DSWAPEFFECT_DISCARD;  FullScreen_PresentationInterval:= D3DPRESENT_INTERVAL_IMMEDIATE; END; Res:= Direct3D.CreateDevice (D3DADAPTER_DEFAULT, DEVT, Form1.Handle, Flag, D3DInit, Device);


And error! No any chance to swith on my device.
But if I recompile (and modify) under D3D9 it works!!

Yes latest driver - but lol each other progs/games works?
Evil Steve
Evil Steve
I'm really confused now [smile]

You do know that the reference device isn't supposed to be used unless you're doing something that requires something your card isn't capable of, but you know others are (E.g. PS v3.0)? The reference device doesn't exist on anyone elses PC unless they have the SDK installed (Which no end users have).

The reference device is an "ideal" device that supports everything, although it won't do hardware vertex processing because it's a software device.

To check for hardware vertex processing, you want to check the devcaps, not the vertex processing caps. You also want to check individual bits, not a generic "If it's not zero my capability is supported".

You want to do something like:
if Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT then Flag:= D3DCREATE_HARDWARE_VERTEXPROCESSING else Flag:= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
Where & is bitwise AND (I don't know what it is in Delphi).

You're checking the vertex processing caps, which are 0x7b (123 in decimal), which means you have the following caps set:
D3DVTXPCAPS_TEXGEN
D3DVTXPCAPS_DIRECTIONALLIGHTS
D3DVTXPCAPS_POSITIONALLIGHTS
D3DVTXPCAPS_LOCALVIEWER
D3DVTXPCAPS_TWEENING



Also, you really shouldn't be checking if D3D returns 0. D3D does not return 0 for success, it returns a SUCCEDED() value. 0 just happens to be one of those values. D3D is perfectly entitled to return 473 if it wants to indicate success. C++ has the SUCCEEDED() and FAILED() macros which you should be using, I assume similar versions exist in Delphi.

I can only assume there's something different between your DX8 and DX9 code that causes it to succeed on one and not the hother.
prux
prux
Yes yes - thank you all helping. Sorry for wasting your time.
The problem was with the SDK - somehow and somewhere I get a new Direct3D8.pas that allways inidcated this error. And, in addition I switched the "allow hardware acceleration" menu ON at the DirectX control panel. I thought this meant the device uses the hardware capability. Nah never mind I can be wrong sometimes.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.