Jump to content
  • Advertisement
Sign in to follow this  
Curin

SwapChain Present Issue

This topic is 546 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!