Sign in to follow this  
Curin

SwapChain Present Issue

Recommended Posts

Hey everyone,
 I'm having a small problem when attempting to move to a UWP code base for SharpDX. I've fixed all problems so far but it errors out with:
     "The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action."
on the following line from TestImageSource.cs in the Present() Function:

            _chain.Present(1, PresentFlags.None, new PresentParameters());

I do know that the Swapchain.Present() suggests using Swapchain.Present1(), but that isn't an available function in any Swapchain version.

Thanks for any help,
     Curin
 
MainPage.cs:
[spoiler]

public sealed partial class MainPage : Page
    {
        private TestImageSource _source;
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void SwapChainPanel_OnLoaded(object sender, RoutedEventArgs e)
        {
            _source = new TestImageSource(SwapChainPanel);

            CompositionTarget.Rendering += CompositionTarget_Rendering;
        }

        private void CompositionTarget_Rendering(object sender, object e)
        {
            _source.List.ClearRenderTargetView(_source._cpuHandle, SharpDX.Color.CornflowerBlue);
            _source.Present();
        }
    }

[/spoiler]

TestImageSource.cs:
[spoiler]

using System;
using System.Threading;
using Windows.ApplicationModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using SharpDX;
using SharpDX.Direct3D12;
using SharpDX.DXGI;
using Device = SharpDX.Direct3D12.Device;
using DXGIDevice = SharpDX.DXGI.Device3;
using Adapter = SharpDX.DXGI.Adapter3;
using Resource = SharpDX.Direct3D12.Resource;
using SwapChain = SharpDX.DXGI.SwapChain3;
using Factory = SharpDX.DXGI.Factory4;
using FeatureLevel = SharpDX.Direct3D.FeatureLevel;

...

public class TestImageSource
    {
        const byte FRAMECOUNT = 2;
        private static Factory _fact = new Factory();

        private long _currentFence;

        private Device _devD3D;
        private DescriptorHeap _rtvHeap;
        private CommandQueue _queue;
        private SwapChain _chain;
        private Adapter _adapt;
        private Resource[] _rtv = new Resource[FRAMECOUNT];
        private CommandList _ComList;
        private Fence _fen;
        private AutoResetEvent _event;
        private DXGIDevice _devDXGI;
        private SwapChainPanel _swapPanel;

        private int _width;
        private int _height;
        private int _rtvDescSize;
        private float _pixelSize;

        private int _frameIndex;
        public CpuDescriptorHandle _cpuHandle;
        private SwapChainDescription1 _chainDesc;
        private DescriptorHeapDescription _rtvHeapDesc;
        private bool _isUsingWarp;

        public GraphicsCommandList List;
        public CommandAllocator Allocator;

        public TestImageSource(SwapChainPanel swapPanel)
        {
            _swapPanel = swapPanel;
            _pixelSize = Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi/96.0f;
            _width = (int)(swapPanel.RenderSize.Width * _pixelSize);
            _height = (int)(swapPanel.RenderSize.Height * _pixelSize);

            CreateDeviceResources();

            Application.Current.Suspending += OnSuspending;
        }

        private void CreateDeviceResources()
        {
            LoadPipeline();
            LoadAssets();
        }

        private void LoadPipeline()
        {
            if (_devD3D == null)
            {
                try
                {
                    _isUsingWarp = false;
                    using (SharpDX.DXGI.Adapter adapt = _fact.GetAdapter(0))
                        _adapt = adapt.QueryInterface<Adapter>();
                    _devD3D = new Device(_adapt, FeatureLevel.Level_12_1);
                }
                finally 
                {
                    _isUsingWarp = true;
                    using (SharpDX.DXGI.Adapter adapt = _fact.GetWarpAdapter())
                        _adapt = adapt.QueryInterface<Adapter>();
                    _devD3D = new Device(_adapt, FeatureLevel.Level_12_1);
                }
            }

            _queue = _devD3D.CreateCommandQueue(new CommandQueueDescription(CommandListType.Direct));

            _chainDesc = new SwapChainDescription1()
            {
                AlphaMode = AlphaMode.Ignore,
                BufferCount = FRAMECOUNT,
                Format = Format.B8G8R8A8_UNorm,
                Height = _height,
                Width = _width,
                SampleDescription = new SampleDescription(1, 0),
                Scaling = Scaling.Stretch,
                Stereo = false,
                SwapEffect = SwapEffect.FlipSequential,
                Usage = Usage.BackBuffer | Usage.RenderTargetOutput
            };

            _devDXGI = new Device3(_devD3D.NativePointer);

            using (Factory3 fact = _adapt.GetParent<Factory3>())
                using (SwapChain1 chain = new SwapChain1(fact, _queue, ref _chainDesc))
                    _chain = chain.QueryInterface<SwapChain3>();

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

            _rtvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = FRAMECOUNT,
                Type = DescriptorHeapType.RenderTargetView,
                Flags = DescriptorHeapFlags.None
            };

            _rtvHeap = _devD3D.CreateDescriptorHeap(_rtvHeapDesc);
            _rtvDescSize = _devD3D.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);

            _cpuHandle = _rtvHeap.CPUDescriptorHandleForHeapStart;

            Allocator = _devD3D.CreateCommandAllocator(CommandListType.Direct);
            List = _devD3D.CreateCommandList(CommandListType.Direct, Allocator, null);
        }

        private void LoadAssets()
        {
            _fen = _devD3D.CreateFence(0, FenceFlags.None);
            _currentFence = 1;

            _event = new AutoResetEvent(false);
            WaitForPrevFrame();
        }

        private void WaitForPrevFrame()
        {
            long localFence = _currentFence;
            _queue.Signal(_fen, localFence);
            _currentFence++;

            if (_fen.CompletedValue < localFence)
            {
                _fen.SetEventOnCompletion(localFence, _event.GetSafeWaitHandle().DangerousGetHandle());
                _event.WaitOne();
            }

            _frameIndex = _chain.CurrentBackBufferIndex;
            _cpuHandle = _rtvHeap.CPUDescriptorHandleForHeapStart;
            _cpuHandle += _frameIndex * _rtvDescSize;

            
        }

        public void Present()
        {
            _queue.ExecuteCommandList(List);
            _chain.Present(1, PresentFlags.None, new PresentParameters());

            WaitForPrevFrame();
        }

        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            throw new NotImplementedException();
        }
    }
}

[/spoiler]

Share this post


Link to post
Share on other sites

This is likely unrelated to the Present call. If you're using D3D12, it's more likely that you have an error somewhere else which is just getting reported out of Present. Are you running with the D3D12 debug layer? How about the GPU-based validation layer? Most likely it would report what's causing your problem.

Share this post


Link to post
Share on other sites

Thank you very much Jesse. I hadn't turned on the Debug layer as I was doing quick tests and forgot. It led me to realize I forgot a bunch of steps that I had put in different spots of my old code, like creating my rendertargets, not just their heaps, and reseting the command list and allocator every frame.

 

Appreciate your Help,

Curin

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this