DirectX12 commandList执行错误
DirectX12 commandList execution error
我已经开始学习DirectX12,我试着做一些简单的引擎。我遵循Frank D. Luna的"DirectX12 3D编程入门",我遇到了一些问题。首先,在创建swapChain时,填写如下描述:
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc.Width = Core::displayWidth;
swapChainDesc.BufferDesc.Height = Core::displayHeight;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.Format = Core::pixelDefinitionFormat;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = Core::multiSamplingLevel ? 4 : 1;
swapChainDesc.SampleDesc.Quality = Core::multiSamplingEnabled ? (Core::multiSamplingLevel - 1) : 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = (INT) Core::buffering;
swapChainDesc.OutputWindow = Core::mainWindow;
swapChainDesc.Windowed = true;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
// Note: Swap chain uses queue to perform flush.
ThrowIfFailed(Core::factory->CreateSwapChain(
Core::commandQueue.Get(),
&swapChainDesc,
Core::swapChain.GetAddressOf()
));
我收到"坏参数"错误。我已经在MSDN上找到了解决方案,但我想知道我做错了什么。
第二个问题是为什么有i:
D3D12 ERROR: ID3D12GraphicsCommandList::*: A single command list cannot write to multiple buffers within a particular swapchain. [ STATE_SETTING ERROR #904: COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES]
在执行此清除屏幕代码片段时:
void Renderer::drawSomething() {
// Reuse the memory associated with command recording.
// We can only reset when the associated command lists have finished
// execution on the GPU.
ThrowIfFailed(Core::commandAllocator->Reset());
// A command list can be reset after it has been added to the
// command queue via ExecuteCommandList. Reusing the command list reuses memory.
ThrowIfFailed(Core::commandList->Reset(Core::commandAllocator.Get(), NULL));
// Set the viewport and scissor rect. This needs to be reset
// whenever the command list is reset.
Core::commandList->RSSetViewports(1, &Core::viewport);
Core::commandList->RSSetScissorRects(1, &Core::scissorsRectangle);
// Indicate a state transition on the resource usage.
Core::commandList->ResourceBarrier(
1,
&CD3DX12_RESOURCE_BARRIER::Transition(
Core::getCurrentBackBuffer().Get(),
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET
)
);
// Specify the buffers we are going to render to.
Core::commandList->OMSetRenderTargets(
1,
&Core::getCurrentBackBufferView(),
true,
&Core::getDSVHeapStartDescriptorHandle()
);
// Clear the back buffer and depth buffer.
Core::commandList->ClearRenderTargetView(
Core::getCurrentBackBufferView(),
DirectX::Colors::LightSteelBlue,
0,
NULL
);
Core::commandList->ClearDepthStencilView(
Core::getDSVHeapStartDescriptorHandle(),
D3D12_CLEAR_FLAGS::D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAGS::D3D12_CLEAR_FLAG_STENCIL,
1.0f,
0,
0,
NULL
);
//// Indicate a state transition on the resource usage.
Core::commandList->ResourceBarrier(
1,
&CD3DX12_RESOURCE_BARRIER::Transition(
Core::getCurrentBackBuffer().Get(),
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT
)
);
// Done recording commands.
ThrowIfFailed(Core::commandList->Close());
// Add the command list to the queue for execution.
ID3D12CommandList* cmdsLists[] = {Core::commandList.Get()};
Core::commandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists);
// swap the back and front buffers
ThrowIfFailed(Core::swapChain->Present(0, 0));
UINT buffering = Core::buffering;
Core::currentBackBuffer = (Core::currentBackBuffer + 1) % buffering;
Core::flushCommandQueue();
}
为了不让这篇文章搞得一团糟,我不会把所有的代码都放在这里,但是如果你想看看它是什么样子的,或者在这种情况下它很重要,我的整个存储库在这里:库
它非常小和简单,几乎所有的代码都放在Core类。
提前感谢!
编辑:我找到了第二个问题的答案。问题在这个循环中:
void Core::createSwapChainBuffersIntoRTVHeap() {
for (UINT i = 0; i < Core::buffering; i++) {
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHeapHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
ErrorUtils::messageAndExitIfFailed(
swapChain->GetBuffer(i, IID_PPV_ARGS(&swapChainBackBuffers[i])),
L"B³¹d pobierania backBuffera!",
GET_SWAPCHAIN_BACK_BUFFER_ERROR
);
device->CreateRenderTargetView(swapChainBackBuffers[i].Get(), NULL, rtvHeapHandle);
//Zapamiêtuje offset, to jest sterta po prostu zwyk³a
rtvHeapHandle.Offset(1, rtvDescriptorSize);
}
}
我只做了一个动作使代码看起来像这样:
void Core::createSwapChainBuffersIntoRTVHeap() {
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHeapHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
for (UINT i = 0; i < Core::buffering; i++) {
ErrorUtils::messageAndExitIfFailed(
swapChain->GetBuffer(i, IID_PPV_ARGS(&swapChainBackBuffers[i])),
L"B³¹d pobierania backBuffera!",
GET_SWAPCHAIN_BACK_BUFFER_ERROR
);
device->CreateRenderTargetView(swapChainBackBuffers[i].Get(), NULL, rtvHeapHandle);
//Zapamiêtuje offset, to jest sterta po prostu zwyk³a
rtvHeapHandle.Offset(1, rtvDescriptorSize);
}
}
。当命令列表关闭正确,我有AccessViolationException在D3D12.dll上:
ThrowIfFailed(Core::swapChain->Present(0, 0));
经过几个小时的互联网研究,我通过使用"dxcpl.exe"在这个应用程序上强制WARP来修复。我想这是因为我在HD4000和Nvidia作为第二卡的笔记本电脑上工作,但我不确定。
这不会帮助您立即解决问题,但会给您更多的信息。DirectX12希望您将所有命令推入命令列表,并且只有在调用Close()
时才会报告错误。注意,你不能"复活"。通过重置Close()
失败的命令列表,您可以做的最好的事情就是删除它,然后创建一个新的命令列表。但是,在这种情况下,您可以不更新引用的资源。我真的不建议你那样做。
你真正能做的是使用ID3D12InfoQueue接口,如果附加了调试器,让你的程序在D3D12错误时中断。
从你的device
获取:
ID3D12InfoQueue* InfoQueue = nullptr;
Core::device->QueryInterface(IID_PPV_ARGS(&InfoQueue));
启用"break on severity"
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, false);
放手吧:
InfoQueue->Release();
您也可以将InfoQueue设置为D3D12错误id的白名单或黑名单。您的错误ID是D3D12_MESSAGE_ID_COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES
(代码904)。
希望这将有助于有人处理这个图形API
- 为什么g++在未执行的代码处标记强制转换错误
- 无法在我的堆排序代码中找到错误.无法正确执行.C++
- GCC:随机构建导致执行期间分段错误
- C++ 随机数生成器:尝试将结果作为向量获取,但通过制作 void 函数来执行此操作而出现错误
- 在 c++ 中执行 BFS 时出现分段错误
- 错误:当我从"WinDbg"打开可执行文件时,找不到符号文件。默认导出 ntdll 的符号.dll
- 甚至在开始执行之前出现分段错误
- 执行错误访问 遍历向量
- 从 C 可执行文件加载动态库时收到错误C++"undefined symbol"
- 解决方案在第 25 行执行错误'out of bounds'
- 表单显示对话框函数错误,并且不执行下面的语句
- "what does ":*** [可执行文件] 错误 1 " mean ?"
- Qt Creator 在执行步骤 "make" 时出现编译错误,-fno-stack-limit
- 这个编译器错误究竟希望我执行什么?
- 执行具有转换错误的过程
- -bash:/a.out:无法执行二进制文件:Exec格式错误
- curl_easy_在Linux上执行分段错误
- 是否可以使函数模板对不适当的类型而不是错误执行默认操作
- 分段错误执行方法
- 未处理的异常错误执行数学操作