Resize ID3D11On12Device::AcquireWrappedResources()中的额外交换链缓冲区引用

Resize ID3D11On12Device::AcquireWrappedResources()中的额外交换链缓冲区引用,resize,direct3d,direct3d11,direct3d12,direct3d11on12,Resize,Direct3d,Direct3d11,Direct3d12,Direct3d11on12,我对使用库很感兴趣,但在调整窗口大小时遇到了麻烦。特别是,我正在修改Visual Studio“DirectX 12应用程序”示例 在示例创建ID3D12CommandQueue之后,我正在创建ID3D11ON12设备: ComPtr<ID3D11Device> d3d11Device; IUnknown* queues[] = { m_commandQueue.Get() }; DX::ThrowIfFailed(D3D11On12CreateDevice(m_d3dDevice.

我对使用库很感兴趣,但在调整窗口大小时遇到了麻烦。特别是,我正在修改Visual Studio“DirectX 12应用程序”示例

在示例创建ID3D12CommandQueue之后,我正在创建ID3D11ON12设备:

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));
到目前为止,一切似乎都按预期进行。但是,调整窗口大小时会出现问题。特别是,调整大小调用IDXGISWAppChain3::ResizeBuffers()。发生这种情况时,ResizeBuffers()返回failure,控制台上显示以下消息:

DXGI ERROR: IDXGISwapChain::ResizeBuffers: Swapchain cannot be resized unless all outstanding buffer references have been released. [ MISCELLANEOUS ERROR #19: ]
我已尝试在ResizeBuffers()之前清除m_wrappedBackBuffers引用:

注释掉ID3D11On12Device::AcquireWrappedResources()和ID3D11On12Device::ReleaseWrappedResources()调用会使ResizeBuffers()成功返回;但调用这两个函数似乎是使用库所必需的

似乎在某个地方,ID3D11ON12设备或ID3D11DeviceContext保留着对交换链缓冲区的引用,但我找不到任何关于如何在不破坏整个设备的情况下重置此引用的文档

GitHub上的这个问题似乎与我遇到的问题相同;但是,响应涉及“在D2D上下文上调用SetTarget(nullptr)”,但我在这个项目中根本没有涉及Direct2D(并且Visual Studio模板已经在IDXGISwapChain3::ResizeBuffers()之前调用WaitForGpu()

微软的根本不包括交换链缓冲区大小调整。运行示例会导致交换链拉伸以适合窗口


我还没有在Microsoft的中找到任何关于调整大小的信息。

您遇到的问题是AcquireWrappedResource和ReleaseWrappedResource方法最终将D3D11即时上下文中的一些工作排队。D3D11On12的语义要求在您希望从D3D11转换到D3D12时显式调用Flush()API,以确保所有排队的命令都正确记录在D3D12命令列表中,然后关闭并提交该列表

如果我正确理解了您的描述,并且您只是在创建包装的资源之后调用了一次Acquire/Release,那么您的问题应该是在Release()之后调用Flush()。这样可确保仅提交引用后台缓冲区0的命令,而后台缓冲区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]
然后,当您准备好调整大小时,请按照以下内容的“清理”部分中的说明进行操作:

  • 释放对D3D11资源的所有引用,包括在其上创建的任何视图
  • 在即时上下文上调用ID3D11DeviceContext::Flush()

  • 完成这两项工作后,您应该能够调整swapchain的大小,而无需任何延迟引用,也无需最终刷新()导致在不适当的时间提交命令。

    Wow!它起作用了!非常感谢你!我希望D3D11->D3D12转换过程中有关Flush()要求的部分在文档中的某个地方!再次感谢!:MSDN页面中的数据:“对于互操作,了解D3D11On12如何与应用程序创建和提供的D3D12对象交互非常重要。为了确保工作以正确的顺序进行,必须先刷新D3D11即时上下文,然后才能向该队列提交其他D3D12工作。”Hrm。看起来还是少了些什么。特别是,如果我将AcquireWrappedResources()/Release移动到render函数,并不断调整大小,则同步似乎不太正确。你有什么想法吗?“在使用ID3D12DescriptorHeap对象的所有GPU操作完成之前,该对象正在最终发布。这是无效的,可能会导致应用程序不稳定。[执行错误#921:对象在仍在使用时被删除]”(代码位于)我没有任何线索。D3D11On12不应该造成这种情况。我在你的应用程序中看到的唯一描述符堆是m_cbvHeap,它看起来只在CreateDeviceDependentResources中创建了一次。感谢你查看它!我想我会在connect.microsoft.com上提交一个bug:)
    DXGI ERROR: IDXGISwapChain::ResizeBuffers: Swapchain cannot be resized unless all outstanding buffer references have been released. [ MISCELLANEOUS ERROR #19: ]
    
    for (UINT n = 0; n < c_frameCount; n++)
    {
        m_renderTargets[n] = nullptr;
        m_wrappedBackBuffers[n] = nullptr;
    }
    
    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.
    
    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]