If you don't zeroe pp object and don't fill some members, those members will get random values (e.g. pp.MultisampleQuality = 135438734 or pp.BackBufferCount = 87684543). So, IDirect3D9::CreateDevice() will fail.
Sorry, I forgot to mention that this is SlimDX. I think this situation is impossible .NET, data members are always initialized.
Check for device support. For example, if you want a HAL device, and D3DFMT_D16 for depthbuffer and D3DFMT_R5G6B5 for backbuffer and the device don't support them, device creation will fail.
The backbuffer format is D3DFMT_UNKNOWN since I'm in windowed mode. This should always work.
The depthbuffer format cannot be the reason, since the call fails even without any depthbuffer.
Here is my code:
PresentParameters parameters = new PresentParameters();
parameters.Windowed = true;
parameters.SwapEffect = SwapEffect.Discard;
parameters.BackBufferCount = 1;
if (windowed)
{
parameters.BackBufferWidth = backbufferSize.Width;
parameters.BackBufferHeight = backbufferSize.Height;
}
else
{
Rectangle screenSize = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
parameters.BackBufferWidth = screenSize.Width;
parameters.BackBufferHeight = screenSize.Height;
}
var currentDisplayFormat = Direct3D.GetAdapterDisplayMode(adapterToUse).Format;
Result result;
bool checkdeviceFormat = Direct3D.CheckDeviceFormat(adapterToUse, deviceType, currentDisplayFormat, Usage.DepthStencil, ResourceType.Surface, depthStencilFormat, out result);
// check whether 24bit is supported
// note: info from gamedev.net: you should both use CheckDeviceFormat AND CheckDepthStencilMatch
if (checkdeviceFormat && Direct3D.CheckDepthStencilMatch(adapterToUse, deviceType, currentDisplayFormat, currentDisplayFormat, depthStencilFormat))
parameters.AutoDepthStencilFormat = depthStencilFormat;
else
parameters.AutoDepthStencilFormat = Format.D16; // fallback
parameters.EnableAutoDepthStencil = true;
if (vSync)
parameters.PresentationInterval = PresentInterval.Default;
else
parameters.PresentationInterval = PresentInterval.Immediate;
parameters.BackBufferFormat = Format.Unknown; // for windowed mode, this takes the current display format.
if (multiSampling)
parameters.Multisample = MyDevice.GetMaximumMultisampleLevel(0, deviceType, parameters);
bool failure = false;
MyDevice device = null;
try
{
device = Create(adapterToUse, deviceType, control, CreateFlags.HardwareVertexProcessing | CreateFlags.FpuPreserve, parameters);
}
catch (Direct3D9Exception exc)
{ failure = true; }
if (failure)
{
failure = false;
try
{
// Hardware vertex processing not available. Trying software...
device = MyDevice.Create(adapterToUse, DeviceType.Hardware, control, CreateFlags.SoftwareVertexProcessing| CreateFlags.FpuPreserve, parameters);
}
catch (Direct3D9Exception)
{ failure = true; }
if (failure || Result.Last.IsFailure)
{
// Both hardware and vertex processing failed.
// Try it without depth buffer.
bool itWorksWithoutDepthBuffer = true;
try{
var paramWithoutDepth = parameters.Clone();
paramWithoutDepth.EnableAutoDepthStencil=false;
device=MyDevice.Create(adapterToUse, DeviceType.Hardware, control, CreateFlags.HardwareVertexProcessing, paramWithoutDepth);}
catch(Direct3D9Exception) { withoutDepthBuffer=false;}
throw new SlimException("Cannot initialize Graphics Card. Without depth buffer = "+itWorksWithoutDepthBuffer);
}
}
Note the exception in the last line. This exception gets sent to me via the internet automatically, no matter whether the last init worked or not. So far, all error reports say "Without depth buffer = false".