Я заинтересован в использовании " Direct 3D 11 на 12-дюймовой библиотеке, но у меня возникают проблемы при изменении размера окна. В частности, я модифицирую образец приложения DirectX 12 для Visual Studio.
Я создаю 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::ResizeBuffers(). Когда это происходит, ResizeBuffers() возвращает ошибку, и на консоли отображается следующее сообщение:
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;
}
но это, кажется, не имеет никакого эффекта. Я также пробовал использовать Flush() и ClearState() для 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 удерживает ссылку на буферы цепочки подкачки, но мне не удалось найти никакой документации о том, как сбросить эту ссылку, не разрушая все устройство.
Эта проблема на GitHub кажется той же проблемой, что и у меня; однако ответ включает «вызов SetTarget(nullptr) в контексте D2D», но я вообще не касался Direct2D в этом проекте (и шаблон Visual Studio уже вызывает WaitForGpu() до IDXGISwapChain3::ResizeBuffers()).
пример от Microsoft не включает буфер цепочки подкачки изменение размера вообще. Запуск примера приводит к тому, что цепочка обмена растягивается, чтобы соответствовать окну.
Я не нашел ничего об изменении размера в Microsoft документация.