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(); } }
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(); } } }