目标:编写“最小可行”,没有设置SharpDX 12(DirectX 12周围的C#包装器)的装饰或附加代码,创建一个窗口,并执行一个将屏幕清除为RGBA的当前循环(0,0 ,1,1)。
期望:尽可能地遵循DirectX 12设置教程,然后我会得到一个蓝色背景的窗口。
结果:在第二次运行循环中,在“swapChain.Present(1,SharpDX.DXGI.PresentFlags.None)”行上;错误消息“SharpDX.SharpDXException:HRESULT:[0x887A0005],模块:[SharpDX.DXGI],ApiCode:[DXGI_ERROR_DEVICE_REMOVED / DeviceRemoved],消息:GPU设备实例已被挂起。使用GetDeviceRemovedReason确定相应的操作。
在SharpDX.Result.CheckError() 在SharpDX.DXGI.SwapChain.Present(Int32 syncInterval,PresentFlags标志) 在DirectX12BlueScreen.Program.Main(String [] args)* \ DirectX12BlueScreen \ DirectX12BlueScreen \ Program.cs:第114行“打印到控制台窗口(我用于调试输出)
我在寻找:错误发生的原因(设备肯定没有被删除);我的代码的哪一部分导致了错误;如果前两条信息不提供该信息,则解决问题。
由于完整代码为165行,我在此处发布了循环,并在pastebin中发布了完整代码:https://pastebin.com/vctaYkNC
while(form.Visible)
{
commandAllocator[0].Reset();
commandList.Reset(commandAllocator[0], null);
commandList.SetViewport(viewport: viewport);
commandList.SetScissorRectangles(rectangle: scissorsRectangle);
commandList.ResourceBarrierTransition(
resource: renderTargets[0],
stateBefore: ResourceStates.Present,
stateAfter: ResourceStates.RenderTarget);
commandList.ClearRenderTargetView(
renderTargetView:
rtvDescriptorHeap.CPUDescriptorHandleForHeapStart,
colorRGBA: new RawColor4(0f, 0f, 1f, 1f));
commandList.ResourceBarrierTransition(
resource: renderTargets[0],
stateBefore: ResourceStates.RenderTarget,
stateAfter: ResourceStates.Present);
commandList.Close();
commandQueue.ExecuteCommandList(commandList);
swapChain.Present(1, SharpDX.DXGI.PresentFlags.None);
Application.DoEvents();
}
编辑:使用PhillipH提供的信息,我现在有一个更准确的错误读数: “System.Runtime.InteropServices.SEHException(0x80004005):外部组件引发了异常。 在SharpDX.Direct3D12.GraphicsCommandList.ClearRenderTargetView(CpuDescriptorHandle renderTargetView,RawColor4 colorRGBA,Int32 numRects,RawRectangle [] rectsRef) 在SharpDX.Direct3D12.GraphicsCommandList.ClearRenderTargetView(CpuDescriptorHandle renderTargetView,RawColor4 colorRGBA) 在* \ DirectX12BlueScreen \ DirectX12BlueScreen \ Program.cs中的DirectX12BlueScreen.Program.Main(String [] args):第138行“
答案 0 :(得分:0)
我没有正确设置渲染目标,而我根本没有使用栅栏。我使用的是SwapChain而不是SwapChain3,因此无法获得当前的缓冲区索引。正确的代码已放入pastebin以供将来参考。
它成功渲染了三分钟,所以我想我可以称之为解决了这个问题。
感谢PhillipH,没有他的帮助,我仍然想知道如何获得好的错误信息。
工作渲染循环:
while (form.Visible)
{
commandAllocator[0].Reset();
commandList.Reset(commandAllocator[0], null);
commandList.ResourceBarrierTransition(
resource: renderTargets[currentBufferIndex],
stateBefore: ResourceStates.Present,
stateAfter: ResourceStates.RenderTarget);
renderTargetView =
rtvDescriptorHeap.CPUDescriptorHandleForHeapStart +
currentBufferIndex *
renderTargetViewHeapSize;
commandList.ClearRenderTargetView(
renderTargetView: renderTargetView,
colorRGBA: new RawColor4(0f, 0f, 1f, 1f));
commandList.ResourceBarrierTransition(
resource: renderTargets[currentBufferIndex],
stateBefore: ResourceStates.RenderTarget,
stateAfter: ResourceStates.Present);
commandList.Close();
commandQueue.ExecuteCommandList(commandList);
swapChain.Present(1, SharpDX.DXGI.PresentFlags.None);
long fenceToWaitFor = fenceValue;
commandQueue.Signal(fence[0], fenceValue);
++fenceValue;
if (fence[0].CompletedValue < fenceValue)
{
fence[0].SetEventOnCompletion(fenceToWaitFor,
fenceEvent.SafeWaitHandle.DangerousGetHandle());
fenceEvent.WaitOne();
fenceEvent.Reset();
}
currentBufferIndex = swapChain.CurrentBackBufferIndex;
Application.DoEvents();
}