首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DirectX12 commandList执行错误

DirectX12 commandList执行错误
EN

Stack Overflow用户
提问于 2016-10-02 15:03:38
回答 1查看 2K关注 0票数 2

我已经开始学习DirectX12,我试着做一些简单的引擎。我遵循弗兰克·D·露娜( Frank .露娜)的“DirectX12 3D编程导论”,我遇到了一些问题。首先,在创建swapChain期间,填充如下描述:

代码语言:javascript
复制
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上找到了解决方案,但是我想知道我做错了什么。

第二个问题是,为何我要:

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]

执行此清除屏幕代码片段:

代码语言:javascript
复制
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类中。

提前谢谢你!

编辑:,我找到了第二个问题的解决方案。这个循环中有问题:

代码语言:javascript
复制
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);
}

}

我只做了一个动作,让这段代码看起来像这样:

代码语言:javascript
复制
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);
}

}

在那之后。当commandList关闭时,我在D3D12.dll中得到了AccessViolationException:

代码语言:javascript
复制
ThrowIfFailed(Core::swapChain->Present(0, 0));

经过几个小时的互联网研究,我修正了使用"dxcpl.exe“强制扭曲这个应用程序的问题。我认为这是因为我在笔记本电脑上使用HD4000和Nvidia作为第二张卡,但我不确定。

EN

回答 1

Stack Overflow用户

发布于 2021-08-10 15:19:25

这将不会帮助您立即解决问题,但会给您提供更多的信息。DirectX12希望您将所有命令推入命令列表中,并且只有在调用Close()时才会报告错误。请注意,您不能通过重置命令列表来“复活”在Close()上失败的命令列表,最好的方法是删除它,然后创建一个新的命令列表。但是,在这种情况下,您可能不会更新引用的资源。别真的建议你这么做。

如果附加了调试器,您确实可以使用ID3D12InfoQueue接口使程序在D3D12错误上中断。

从你的device上得到它

代码语言:javascript
复制
ID3D12InfoQueue* InfoQueue = nullptr;
Core::device->QueryInterface(IID_PPV_ARGS(&InfoQueue));

启用“中断严重性”:

代码语言:javascript
复制
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
InfoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, false);

让它去吧:

代码语言:javascript
复制
InfoQueue->Release();

还可以将InfoQueue设置为D3D12错误ids的白名单或黑名单集。您的错误ID是D3D12_MESSAGE_ID_COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES (代码904)。

希望这将有助于人们处理这个图形API。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39818316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档