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]