1

目标:编写“最小可行”,没有多余的代码来设置 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 flags) 在 DirectX12BlueScreen.Program.Main(String[] args) 在 *\DirectX12BlueScreen\DirectX12BlueScreen\Program.cs:line 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): External component has throw an exception. at SharpDX.Direct3D12.GraphicsCommandList.ClearRenderTargetView(CpuDescriptorHandle renderTargetView, RawColor4 colorRGBA , Int32 numRects, RawRectangle[] rectsRef) 在 SharpDX.Direct3D12.GraphicsCommandList.ClearRenderTargetView(CpuDescriptorHandle renderTargetView, RawColor4 colorRGBA) 在 DirectX12BlueScreen.Program.Main(String[] args) 在 *\DirectX12BlueScreen\DirectX12BlueScreen\Program.cs:line 138"

4

1 回答 1

0

我没有正确设置渲染目标,我根本没有使用栅栏。我使用的是 SwapChain 而不是 SwapChain3,因此无法获取当前缓冲区索引。正确的代码已放入 pastebin 以供将来参考。

它按预期成功渲染了三分钟,所以我想我可以称之为解决。

感谢 PhillipH,没有他的帮助,我仍然想知道如何获得好的错误消息。

https://pastebin.com/Ku7wqHpJ

工作渲染循环:

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();
}
于 2017-06-25T22:41:14.883 回答