SharpDX createswapchain failed

Started by
6 comments, last by skidrow1982 12 years, 5 months ago
Hi, all<br />I am using sharpdx now, and CreateSwapChainAndDevice success for me but if I only want to create swap chain with existing device, then it's failed, can some one help me?<br /><br /> SharpDX.Direct3D11.Device CreateOnlyDevice()<br />        {<br />            int adapterNo = 0; // TODO: Initialize to an appropriate value<br />            DX11AdapterList adaList = new DX11AdapterList();<br />            Factory1 factory = new Factory1();<br />            adaList.Enumerate(factory);<br />            DX11Adapter adapter = adaList.Adapter(adapterNo);<br />            FeatureLevel[] feature_levels = <br />                {<br />                    //FeatureLevel.Level_11_0,<br />                    FeatureLevel.Level_10_1,<br />                    FeatureLevel.Level_10_0,<br />                    FeatureLevel.Level_9_3<br />                };<br />            SharpDX.Direct3D11.Device actual =<br />                new SharpDX.Direct3D11.Device(adapter.Adapter, DeviceCreationFlags.Debug, feature_levels);<br />            return actual;<br />        }<br /><br />        public SwapChain CreateDeviceAndSwapChain()<br />        {<br />            System.Windows.Forms.Form form = new System.Windows.Forms.Form();<br />            <br />            SharpDX.Direct3D11.Device device = CreateOnlyDevice();<br />            int quality = device.CheckMultisampleQualityLevels(Format.R8G8B8A8_UNorm, 8);<br />            device.Dispose();<br /><br />            DriverType driverType = DriverType.Hardware; // TODO: Initialize to an appropriate value<br />            DeviceCreationFlags flags = DeviceCreationFlags.Debug; // TODO: Initialize to an appropriate value<br />            FeatureLevel[] feature_levels = <br />                {<br />                    FeatureLevel.Level_11_0,<br />                    FeatureLevel.Level_10_1,<br />                    FeatureLevel.Level_10_0,<br />                    FeatureLevel.Level_9_3<br />                };<br />            SwapChainDescription desc = new SwapChainDescription();<br />            desc.BufferCount = 1;<br />            desc.ModeDescription = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm);<br />            desc.ModeDescription.ScanlineOrdering = DisplayModeScanlineOrder.Unspecified;<br />            desc.ModeDescription.Scaling = DisplayModeScaling.Unspecified;<br />            desc.Usage = Usage.RenderTargetOutput;<br />            desc.OutputHandle = form.Handle;<br />            desc.SampleDescription.Count = 8;<br />            desc.SampleDescription.Quality = quality -1;<br />            desc.IsWindowed = true;<br />            desc.SwapEffect = SwapEffect.Discard;<br />            desc.Flags = SwapChainFlags.AllowModeSwitch;<br /><br />            SwapChain swapChain = null; // TODO: Initialize to an appropriate value<br />            DX11RenderFactory.Instance.CreateSwapChain(driverType, flags, feature_levels, desc, out swapChain);<br />            return swapChain;<br />        }<br /><br />I am running my program in .net unit test project<br />Here are the two tests I did using two functions above.<br /><br />  /// <summary><br />        ///A test for CreateSwapChain<br />        ///</summary><br />        [TestMethod()]<br />        public void CreateSwapChainTest()<br />        {<br />            SwapChain tempSwapChain = CreateDeviceAndSwapChain();<br />            try<br />            {<br />                SwapChain swapChain = new SwapChain(DX11RenderFactory.Instance.DxgiFactory, <br />                    DX11RenderFactory.Instance.D3DDevice, tempSwapChain.Description);<br />            }<br />            catch (System.Exception ex)<br />            {<br />                System.Console.Write(ex.Message);<br />            }<br />            Assert.Inconclusive("A method that does not return a value cannot be verified.");<br />        }<br /><br />        /// <summary><br />        ///A test for CreateSwapChain<br />        ///</summary>s<br />        [TestMethod()]<br />        public void CreateSwapChainTest1()<br />        {<br />            SwapChain swapChain = CreateDeviceAndSwapChain();<br />            Assert.AreNotEqual(null, DX11RenderFactory.Instance.D3DDevice);<br />            Assert.AreNotEqual(null, swapChain);<br />            Assert.Inconclusive("A method that does not return a value cannot be verified.");<br />        }<br /><br />and the first test failed, the second test pass.<br />But I checked in the first test, d3ddevice ,dxgiFactory is successfully created, however  <br />SwapChain swapChain = new SwapChain(DX11RenderFactory.Instance.DxgiFactory, <br />                    DX11RenderFactory.Instance.D3DDevice, tempSwapChain.Description);<br />throw a exception {"Unknown error (HRESULT = 0x887A0001)"}<br />
Advertisement
Woo boy, this is why I always preview my posts before I submit. You're going to have to reformat that whole post (and code) before people can help you.
If you run in debug mode with the option "Enable unmanaged code debugging" in your project, you would have seen this error:

IDXGIFactory::CreateSwapChain: This function is being called with a device from a different IDXGIFactory.

When you create a swap chain from a device, they need to share the same factory but in your code you are creating D3D11Device with one factory (Factory1 factory = new Factory1();) and the swap chain with another (DX11RenderFactory.Instance.DxgiFactory)

If you run this code, It is working with no exceptions:

Factory factory = new Factory();
var adapter = factory.GetAdapter(0);
Device device = new Device(adapter, DeviceCreationFlags.Debug);
SwapChain swapChain = new SwapChain(factory, device, desc);

(And yes, please, preview and reformat your code next time)

If you run in debug mode with the option "Enable unmanaged code debugging" in your project, you would have seen this error:

IDXGIFactory::CreateSwapChain: This function is being called with a device from a different IDXGIFactory.

When you create a swap chain from a device, they need to share the same factory but in your code you are creating D3D11Device with one factory (Factory1 factory = new Factory1();) and the swap chain with another (DX11RenderFactory.Instance.DxgiFactory)

If you run this code, It is working with no exceptions:

Factory factory = new Factory();
var adapter = factory.GetAdapter(0);
Device device = new Device(adapter, DeviceCreationFlags.Debug);
SwapChain swapChain = new SwapChain(factory, device, desc);

(And yes, please, preview and reformat your code next time)


Sorry for the layout problem, in the office gamedev is affected by blocking policy, the css is totally wrong, so when i edit my post, everything messed up. I will post at home next time.
Thank u , Alexandre, I figured out the problem, I did use the same Factory, the Factory1 factory = new Factory1(); you saw is a temporary one I created just to check multisampleing quality,nothing else,
but i notice if i use the constructor Device.CreateSwapChainAndDevice(drivertype,....) , every time it will reallocate a new factory for my device and swap chain implicitly,
because i have a singleton which holds Factory1 and D3D Device, so if i want to create a new swapchain using same device
(created using Device.CreateWithSwapChain(driverType, flags, featureLevels, desc,out d3dDevice_, out swapChain);
I have to reset my factory. Here is the code I fixed:
I have 2 remaining questions:
1.do I need to call dispose for dxgiFacotry_, d3dDevice_, dxContext_ before Device.CreateWithSwapChain?? in first function below?
2. original API CreateDeviceAndSwapChain can take Adapter and DriverType together as parameters , in SharpDx, seems constructor can only take either Adapter or DriverType one of them,
so if I use constructor which takes DriverType as parameter to create device and swapchain, is it only bind to the first Adapter? Any reason for these two can not passed in together?

// Create a new device and swapchain with a new DXGI factory1
public SwapChain CreateSwapChainAndDevice(DriverType driverType, DeviceCreationFlags flags,
FeatureLevel[] featureLevels, SwapChainDescription desc)
{
SwapChain swapChain;
Device.CreateWithSwapChain(driverType, flags, featureLevels, desc,out d3dDevice_, out swapChain);
dxgiFacotry_ = swapChain.GetParent<Factory1>();
dxContext_ = d3dDevice_.ImmediateContext;
return swapChain;
}

// in this case, device is already created, create additional swapchain with existed DXGI factory1
public SwapChain CreateSwapChain(SwapChainDescription swdesc)
{
return new SwapChain(dxgiFacotry_, d3dDevice_, swdesc);
}

I have 2 remaining questions:
1.do I need to call dispose for dxgiFacotry_, d3dDevice_, dxContext_ before Device.CreateWithSwapChain?? in first function below?

If you are overriding previous values, you should probably dispose previous dxgiFactory and d3dDevice (context is released by device).

Also you should be able to create Device/SwapChain with their respective constructors, using the same DXGI factory/adapter for all calls, without having to use static Device.CreateWithSwapChain method.


2. original API CreateDeviceAndSwapChain can take Adapter and DriverType together as parameters , in SharpDx, seems constructor can only take either Adapter or DriverType one of them,
so if I use constructor which takes DriverType as parameter to create device and swapchain, is it only bind to the first Adapter? Any reason for these two can not passed in together?

If you look at D3D11CreateDeviceAndSwapChain documentation, in remarks, it is stated:
"If you set the pAdapter parameter to a non-NULL value, you must also set the DriverType parameter to the D3D_DRIVER_TYPE_UNKNOWN value. If you set the pAdapter parameter to a non-NULL value and the DriverType parameter to the D3D_DRIVER_TYPE_HARDWARE value, D3D11CreateDeviceAndSwapChain returns an HRESULT of E_INVALIDARG."

That's why SharpDX doesn't expose Adapter and DriverType together, as when you are passing an Adapter, the DriverType mush always be set to Unknown.

[quote name='skidrow1982' timestamp='1320493715' post='4880745']
I have 2 remaining questions:
1.do I need to call dispose for dxgiFacotry_, d3dDevice_, dxContext_ before Device.CreateWithSwapChain?? in first function below?

If you are overriding previous values, you should probably dispose previous dxgiFactory and d3dDevice (context is released by device).

Also you should be able to create Device/SwapChain with their respective constructors, using the same DXGI factory/adapter for all calls, without having to use static Device.CreateWithSwapChain method.


2. original API CreateDeviceAndSwapChain can take Adapter and DriverType together as parameters , in SharpDx, seems constructor can only take either Adapter or DriverType one of them,
so if I use constructor which takes DriverType as parameter to create device and swapchain, is it only bind to the first Adapter? Any reason for these two can not passed in together?

If you look at D3D11CreateDeviceAndSwapChain documentation, in remarks, it is stated:
"If you set the pAdapter parameter to a non-NULL value, you must also set the DriverType parameter to the D3D_DRIVER_TYPE_UNKNOWN value. If you set the pAdapter parameter to a non-NULL value and the DriverType parameter to the D3D_DRIVER_TYPE_HARDWARE value, D3D11CreateDeviceAndSwapChain returns an HRESULT of E_INVALIDARG."

That's why SharpDX doesn't expose Adapter and DriverType together, as when you are passing an Adapter, the DriverType mush always be set to Unknown.
[/quote]

thanks again,
I ran into a new problem, the same unit test code passed test on office machine, but when i ran on my home's pc, it failed, I opened debug unmanaged code in debug mode and caught sharpdxexception only said "Unknown error (HRESULT = 0x80004005)" at SharpDX.Result.CheckError()
at SharpDX.Direct3D11.D3D11.CreateDevice(Adapter adapterRef, DriverType driverType, IntPtr software, DeviceCreationFlags flags, FeatureLevel[] featureLevelsRef, Int32 featureLevels, Int32 sDKVersion, Device deviceOut, FeatureLevel& featureLevelRef, DeviceContext& immediateContextOut)
my pc has 2x GTX260 card ,
I attached the unit test failure screen shot and also if i change DeviceCreationFlags in the following line to DeviceCreationFlags.None then it will create device succssfully.
actual = new SharpDX.Direct3D11.Device(adapter.Adapter, DeviceCreationFlags.Debug, feature_levels);
where can be the problem of this?

I attached the unit test failure screen shot and also if i change DeviceCreationFlags in the following line to DeviceCreationFlags.None then it will create device succssfully.
actual = new SharpDX.Direct3D11.Device(adapter.Adapter, DeviceCreationFlags.Debug, feature_levels);
where can be the problem of this?

Creating a D3D10/D3D11 device in Debug mode is looking for DLLs (for example, D3D11SDKLayers.dll) that are only installed by the DirectX SDK (They are not part of the redistributable DirectX runtime and thus must be only used in development phase. To solve your problem, you need to install DirectX June 2010 SDK

[quote name='skidrow1982' timestamp='1320624440' post='4881205']
I attached the unit test failure screen shot and also if i change DeviceCreationFlags in the following line to DeviceCreationFlags.None then it will create device succssfully.
actual = new SharpDX.Direct3D11.Device(adapter.Adapter, DeviceCreationFlags.Debug, feature_levels);
where can be the problem of this?

Creating a D3D10/D3D11 device in Debug mode is looking for DLLs (for example, D3D11SDKLayers.dll) that are only installed by the DirectX SDK (They are not part of the redistributable DirectX runtime and thus must be only used in development phase. To solve your problem, you need to install DirectX June 2010 SDK
[/quote]

thanks, i got it.

This topic is closed to new replies.

Advertisement