Exception when creating Swap Chain with CreateSwapChainForComposition

1

I am trying to render DirectX12 in SwapChainPanel by using SharpDx but creating a SwapChain fails for an unknown reason. Here is a simplified version of what I have:

// select adapter based on some simple scoring mechanism
SelectedAdapter = SelectAdapter();

// create device
using (var defaultDevice = new Device(SelectedAdapter, FeatureLevel.Level_12_0))
    Device = defaultDevice.QueryInterface<SharpDX.Direct3D12.Device2>();

// describe swap chain
SwapChainDescription1 swapChainDescription = new SwapChainDescription1
{
    AlphaMode = AlphaMode.Ignore,
    BufferCount = 2,
    Format = Format.R8G8B8A8_UNorm,
    Height = (int)(MainSwapChainPanel.RenderSize.Height),
    Width = (int)(MainSwapChainPanel.RenderSize.Width),
    SampleDescription = new SampleDescription(1, 0),
    Scaling = Scaling.Stretch,
    Stereo = false,
    SwapEffect = SwapEffect.FlipSequential,
    Usage = Usage.RenderTargetOutput
};

// create swap chain
using (var factory2 = SelectedAdapter.GetParent<Factory2>())
{
    /*--> throws exception:*/
    SwapChain1 swapChain1 = new SwapChain1(factory2, Device, ref swapChainDescription);
    SwapChain = swapChain1.QueryInterface<SwapChain2>();
}

// tie created swap chain with swap chain panel
using (ISwapChainPanelNative nativeObject = ComObject.As<ISwapChainPanelNative>(MainSwapChainPanel))
    nativeObject.SwapChain = SwapChain;

Selection of adapter works as expected (I have 2 adapters + software adapter). I can create a device and I can see that the app in task manager is using that selected adapter.

Creation of the swap chain is based mostly on this documentation here: https://docs.microsoft.com/en-us/windows/uwp/gaming/directx-and-xaml-interop#swapchainpanel-and-gaming

I get factory2 (with all the adapters and other things enumerated). Constructor of SwapChain1 internally is using factory2 to create a swap chain: https://github.com/sharpdx/SharpDX/blob/master/Source/SharpDX.DXGI/SwapChain1.cs#L64

I compared this method with several others examples and tutorials and this is the way it should be done, however, regardless of the Format I choose or adapter, I keep getting this exception:

{SharpDX.SharpDXException: HRESULT: [0x887A0001], Module: [SharpDX.DXGI], ApiCode: [DXGI_ERROR_INVALID_CALL/InvalidCall], Message: The application made a call that is invalid. Either the parameters of the call or the state of some object was incorrect. Enable the D3D debug layer in order to see details via debug messages.

at SharpDX.Result.CheckError() at SharpDX.DXGI.Factory2.CreateSwapChainForComposition(IUnknown deviceRef, SwapChainDescription1& descRef, Output restrictToOutputRef, SwapChain1 swapChainOut) at SharpDX.DXGI.SwapChain1..ctor(Factory2 factory, ComObject device, SwapChainDescription1& description, Output restrictToOutput) at UI.MainPage.CreateSwapChain()}

DebugLayer doesn't show any additional info.

The app itself is a regular Windows Universal Blank App (min target version Creators Update 15063). I know I can run Directx12 on my current hardware (C++ hello world works just fine).

Any ideas what is wrong?

c#
xaml
uwp
sharpdx
directx-12
asked on Stack Overflow Aug 31, 2018 by x3derr8

1 Answer

0

This is how I got it working:

try
{
    using (var factory4 = new Factory4())
    {
        SwapChain1 swapChain1 = new SwapChain1(factory4, CommandQueue, ref swapChainDescription);
        SwapChain = swapChain1.QueryInterface<SwapChain2>();
    }
 }
 catch (Exception e)
 {
     Debug.WriteLine(e.Message);
     return;
 }

 using (ISwapChainPanelNative nativeObject = ComObject.As<ISwapChainPanelNative>(MainSwapChainPanel))
     nativeObject.SwapChain = SwapChain;

So basically I need Factory4 interface to create temporary SwapChain1 from which I can query SwapChain2, then this SwapChain2 can be attached to SwapChainPanel.

Also, a very important thing to notice here is that even though SwapChain1 constructor signature (and documentation) https://github.com/sharpdx/SharpDX/blob/master/Source/SharpDX.DXGI/SwapChain1.cs#L51 says that 2nd argument should be device - it shouldn't. What you need to pass is a CommandQueue object. I have no idea why.

Also, constructor of SwapChain1 says it needs Factory2, but no, you have to pass Factory4!

answered on Stack Overflow Sep 10, 2018 by x3derr8 • edited Sep 10, 2018 by x3derr8

User contributions licensed under CC BY-SA 3.0