我对使用“12号直接3D 11”库感兴趣,但在调整窗口大小时遇到了麻烦。特别是,我正在修改Visual "DirectX 12 App“示例。
我正在创建ID3D11On12Device,就在示例创建ID3D12CommandQueue之后:
ComPtr<ID3D11Device> d3d11Device;
IUnknown* queues[] = { m_commandQueue.Get() };
DX::ThrowIfFailed(D3D11On12CreateDevice(m_d3dDevice.Get(), D3D11_CREATE_DEVICE_BGRA_SUPPORT, nullptr, 0, queues, 1, 0, d3d11Device.GetAddressOf(), m_d3d11DeviceContext.GetAddressOf(), nullptr));
DX::ThrowIfFailed(d3d11Device.As(&m_d3d11On12Device));
然后,当示例创建其呈现目标视图时,我添加了包装ID3D11Resource的创建:
for (UINT n = 0; n < c_frameCount; n++)
{
// Visual studio template calls m_swapChain->GetBuffer() and m_d3dDevice->CreateRenderTargetView() here
D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET };
DX::ThrowIfFailed(m_d3d11On12Device->CreateWrappedResource(m_renderTargets[n].Get(), &d3d11Flags, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT, IID_PPV_ARGS(&m_wrappedBackBuffers[n])));
rtvDescriptor.Offset(m_rtvDescriptorSize);
...
// m_renderTargets[n]->SetName(), etc.
}
然后,在创建了其余的D3D12资源之后,我将测试ID3D11On12Device::AcquireWrappedResources()和ID3D11On12Device::ReleaseWrappedResources() (就像测试一样,试图使代码尽可能简单)
ID3D11Resource* resources[] = { m_wrappedBackBuffers[0].Get() };
m_d3d11On12Device->AcquireWrappedResources(resources, 1);
m_d3d11On12Device->ReleaseWrappedResources(resources, 1);
到目前为止,一切似乎都如期而至。但是,在调整窗口大小时会出现问题。特别是,调整大小调用IDXGISwapChain3 3::ResizeBuffers()。当发生这种情况时,ResizeBuffers()返回failure,并在控制台上显示以下消息:
DXGI ERROR: IDXGISwapChain::ResizeBuffers: Swapchain cannot be resized unless all outstanding buffer references have been released. [ MISCELLANEOUS ERROR #19: ]
在m_wrappedBackBuffers ()之前,我已经尝试过清除ResizeBuffers引用:
for (UINT n = 0; n < c_frameCount; n++)
{
m_renderTargets[n] = nullptr;
m_wrappedBackBuffers[n] = nullptr;
}
但这似乎没有任何效果。我还尝试了ClearState()ing和ID3D11DeviceContext (),但是这些方法似乎没有效果,或者产生了以下错误:
D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists: A command list, which writes to a swapchain back buffer, may only be executed when that back buffer is the back buffer will be presented during the next call to Present*. Such a back buffer is also referred to as the "current back buffer". [ STATE_SETTING ERROR #907: EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE]
D3D12: Removing Device.
注释掉ID3D11On12Device::AcquireWrappedResources()和ID3D11On12Device::ReleaseWrappedResources()调用将使ResizeBuffers()成功返回;但似乎调用这两个函数才能使用库。
似乎在某个地方,ID3D11On12Device或ID3D11DeviceContext保留了对交换链缓冲区的引用,但我还没有找到任何关于如何在不破坏整个设备的情况下重置该引用的文档。
这个问题 on GitHub似乎也是我遇到的问题;然而,响应涉及到“在D2D上下文上调用SetTarget(nullptr)”,但是在这个项目中,我根本没有触及Direct2D (而且Visual模板已经在IDXGISwapChain3 3之前调用了WaitForGpu()::ResizeBuffers())。
微软的示例根本不包括交换链缓冲区大小调整。运行示例将使交换链被拉伸以适应窗口。
我还没有在微软的文档中找到任何关于调整大小的信息。
发布于 2015-12-15 04:48:18
您遇到的问题是,AcquireWrappedResource和ReleaseWrappedResource方法最终会排队处理D3D11即时上下文的一些工作。D3D11On12的语义要求在您想从D3D11转换到D3D12时显式地调用D3D12 () API,以确保所有排队的命令都正确地记录在一个D3D12命令列表中,然后该命令列表被关闭并提交。
如果我已经正确地理解了您的描述,并且在创建包装资源之后只调用了一次获取/发布,那么您的问题应该仅仅是在版本()之后调用刷新()。这确保引用back缓冲区0的命令仅被提交,而back缓冲器0是交换链的当前回缓冲区,从而解决了错误:
D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists: A command list, which writes to a swapchain back buffer, may only be executed when that back buffer is the back buffer will be presented during the next call to Present*. Such a back buffer is also referred to as the "current back buffer". [ STATE_SETTING ERROR #907: EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE]
然后,当您准备调整大小时,请按照D3D11On12 MSDN文档的“清理”部分中的说明操作
一旦完成了这两件事,就应该能够调整swapchain的大小,而不需要任何挥之不去的引用,并且不需要在不适当的时候提交命令。
https://stackoverflow.com/questions/34257212
复制相似问题