A player of my game contacted me, because the game crashes during start-up. After taking a look into log file he sent me, calling CreateSwapChain results in an exception as shown below.
HRESULT: [0x887A0001], Module: [SharpDX.DXGI], ApiCode: [DXGI_ERROR_INVALID_CALL/InvalidCall], Message: Unknown
at SharpDX.Result.CheckError()
at SharpDX.DXGI.Factory.CreateSwapChain(ComObject deviceRef, SwapChainDescription& descRef, SwapChain swapChainOut)
at SharpDX.Direct3D11.Device.CreateWithSwapChain(Adapter adapter, DriverType driverType, DeviceCreationFlags flags, FeatureLevel[] featureLevels, SwapChainDescription swapChainDescription, Device& device, SwapChain& swapChain)
at SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType driverType, DeviceCreationFlags flags, SwapChainDescription swapChainDescription, Device& device, SwapChain& swapChain)
In order to investigate this player's problem, I created a test application that looks like this:
class Program
{
static void Main(string[] args)
{
Helper.UserInfo userInfo = new Helper.UserInfo(true);
Console.WriteLine("Checking adapters.");
using (var factory = new SharpDX.DXGI.Factory1())
{
for (int i = 0; i < factory.GetAdapterCount(); i++)
{
SharpDX.DXGI.Adapter adapter = factory.GetAdapter(i);
Console.WriteLine("\tAdapter {0}: {1}", i, adapter.Description.Description);
bool supportsLevel10_1 = SharpDX.Direct3D11.Device.IsSupportedFeatureLevel(adapter, SharpDX.Direct3D.FeatureLevel.Level_10_1);
Console.WriteLine("\t\tSupport for Level_10_1? {0}!", supportsLevel10_1);
Console.WriteLine("\t\tCreate refresh rate (60).");
var refreshRate = new SharpDX.DXGI.Rational(60, 1);
Console.WriteLine("\t\tCreate mode description.");
var modeDescription = new SharpDX.DXGI.ModeDescription(0, 0, refreshRate, SharpDX.DXGI.Format.R8G8B8A8_UNorm);
Console.WriteLine("\t\tCreate sample description.");
var sampleDescription = new SharpDX.DXGI.SampleDescription(1, 0);
Console.WriteLine("\t\tCreate swap chain description.");
var desc = new SharpDX.DXGI.SwapChainDescription()
{
// Numbers of back buffers to use on the SwapChain
BufferCount = 1,
ModeDescription = modeDescription,
// Do we want to use a windowed mode?
IsWindowed = true,
Flags = SharpDX.DXGI.SwapChainFlags.None,
OutputHandle = Process.GetCurrentProcess().MainWindowHandle,
// Cout in 'SampleDescription' means the level of anti-aliasing (from 1 to usually 4)
SampleDescription = sampleDescription,
SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
// DXGI_USAGE_RENDER_TARGET_OUTPUT: This value is used when you wish to draw graphics into the back buffer.
Usage = SharpDX.DXGI.Usage.RenderTargetOutput
};
try
{
Console.WriteLine("\t\tCreate device (Run 1).");
SharpDX.Direct3D11.Device device = new SharpDX.Direct3D11.Device(adapter, SharpDX.Direct3D11.DeviceCreationFlags.None, new SharpDX.Direct3D.FeatureLevel[]
{
SharpDX.Direct3D.FeatureLevel.Level_10_1
});
Console.WriteLine("\t\tCreate swap chain (Run 1).");
SharpDX.DXGI.SwapChain swapChain = new SharpDX.DXGI.SwapChain(factory, device, desc);
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION: {0}", e.Message);
}
try
{
Console.WriteLine("\t\tCreate device (Run 2).");
SharpDX.Direct3D11.Device device = new SharpDX.Direct3D11.Device(adapter, SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport, new SharpDX.Direct3D.FeatureLevel[]
{
SharpDX.Direct3D.FeatureLevel.Level_10_1
});
Console.WriteLine("\t\tCreate swap chain (Run 2).");
SharpDX.DXGI.SwapChain swapChain = new SharpDX.DXGI.SwapChain(factory, device, desc);
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION: {0}", e.Message);
}
try
{
Console.WriteLine("\t\tCreate device (Run 3).");
SharpDX.Direct3D11.Device device = new SharpDX.Direct3D11.Device(adapter);
Console.WriteLine("\t\tCreate swap chain (Run 3).");
SharpDX.DXGI.SwapChain swapChain = new SharpDX.DXGI.SwapChain(factory, device, desc);
}
catch (Exception e)
{
Console.WriteLine("EXCEPTION: {0}", e.Message);
}
}
}
Console.WriteLine("FIN.");
Console.ReadLine();
}
}
In the beginning, I am collecting information about the computer (processor, GPU, .NET Framework version, etc.). The rest should explain itself. I sent him the application and in all three cases, creating the swap chain fails with the same exception.
In this test program, I included all solutions that worked for other users. For example, AlexandreMutel said in this forum thread, that device and swap chain need to share the same factory. I did that in my program. So using different factories is not a problem in my case. Laurent Couvidou said here:
The player has Windows 7 with .NET Framework 4.6.1, which is good enough to run my test application or game which use .NET Framework 4.5.2. The graphics cards (Radeon HD 6700 Series) is also good enough to run the application. In my test application, I also checked, if Feature Level 10_1 is supported, which is the minimum requirement for my game. A refresh rate of 60 Hz should also be no problem. Therefore, I think the parameters are fine. The remaining calls are just three different ways to create a device and a swap chain for the adapter. All of them throw an exception when creating the swap chain.
There are also Battlefield 3 players who had problems with running BF3. As it turned out, BF3 had some issue with Windows region settings. But I believe that's not a problem in my case. There were also compatibility issues in Fallout 4, but my game runs on many other Windows 7 PCs without any problems.
Do you have any idea what's wrong? I already have a lot of players that play my game without any issues, so it's not a general problem. I really want to help this player, but I currently can't find a solution.
↧