rhi: d3d12: Fix finish() when called outside a frame

Pick-to: 6.8
Fixes: QTBUG-133454
Change-Id: I447610917966a9dcd4b80dc8b84156ce985f9ca9
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
(cherry picked from commit 01308ff18e74860dd32472bbff31ca1fabd8339f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Laszlo Agocs 2025-02-03 14:37:40 +01:00 committed by Qt Cherry-pick Bot
parent 987ff07a85
commit 6446d865be

View File

@ -1900,57 +1900,57 @@ QRhi::FrameOpResult QRhiD3D12::endOffscreenFrame(QRhi::EndFrameFlags flags)
QRhi::FrameOpResult QRhiD3D12::finish() QRhi::FrameOpResult QRhiD3D12::finish()
{ {
if (!inFrame)
return QRhi::FrameOpSuccess;
QD3D12CommandBuffer *cbD = nullptr; QD3D12CommandBuffer *cbD = nullptr;
if (offscreenActive) { if (inFrame) {
Q_ASSERT(!currentSwapChain); if (offscreenActive) {
cbD = offscreenCb[currentFrameSlot]; Q_ASSERT(!currentSwapChain);
} else { cbD = offscreenCb[currentFrameSlot];
Q_ASSERT(currentSwapChain); } else {
cbD = &currentSwapChain->cbWrapper; Q_ASSERT(currentSwapChain);
cbD = &currentSwapChain->cbWrapper;
}
if (!cbD)
return QRhi::FrameOpError;
Q_ASSERT(cbD->recordingPass == QD3D12CommandBuffer::NoPass);
D3D12GraphicsCommandList *cmdList = cbD->cmdList;
HRESULT hr = cmdList->Close();
if (FAILED(hr)) {
qWarning("Failed to close command list: %s",
qPrintable(QSystemError::windowsComString(hr)));
return QRhi::FrameOpError;
}
ID3D12CommandList *execList[] = { cmdList };
cmdQueue->ExecuteCommandLists(1, execList);
releaseQueue.activatePendingDeferredReleaseRequests(currentFrameSlot);
} }
if (!cbD)
return QRhi::FrameOpError;
Q_ASSERT(cbD->recordingPass == QD3D12CommandBuffer::NoPass);
D3D12GraphicsCommandList *cmdList = cbD->cmdList;
HRESULT hr = cmdList->Close();
if (FAILED(hr)) {
qWarning("Failed to close command list: %s",
qPrintable(QSystemError::windowsComString(hr)));
return QRhi::FrameOpError;
}
ID3D12CommandList *execList[] = { cmdList };
cmdQueue->ExecuteCommandLists(1, execList);
releaseQueue.activatePendingDeferredReleaseRequests(currentFrameSlot);
// full blocking wait for everything, frame slots do not matter now // full blocking wait for everything, frame slots do not matter now
waitGpu(); waitGpu();
hr = cmdAllocators[currentFrameSlot]->Reset(); if (inFrame) {
if (FAILED(hr)) { HRESULT hr = cmdAllocators[currentFrameSlot]->Reset();
qWarning("Failed to reset command allocator: %s", if (FAILED(hr)) {
qPrintable(QSystemError::windowsComString(hr))); qWarning("Failed to reset command allocator: %s",
return QRhi::FrameOpError; qPrintable(QSystemError::windowsComString(hr)));
return QRhi::FrameOpError;
}
if (!startCommandListForCurrentFrameSlot(&cbD->cmdList))
return QRhi::FrameOpError;
cbD->resetState();
shaderVisibleCbvSrvUavHeap.perFrameHeapSlice[currentFrameSlot].head = 0;
smallStagingAreas[currentFrameSlot].head = 0;
bindShaderVisibleHeaps(cbD);
} }
if (!startCommandListForCurrentFrameSlot(&cmdList)) releaseQueue.releaseAll();
return QRhi::FrameOpError;
cbD->resetState();
shaderVisibleCbvSrvUavHeap.perFrameHeapSlice[currentFrameSlot].head = 0;
smallStagingAreas[currentFrameSlot].head = 0;
bindShaderVisibleHeaps(cbD);
releaseQueue.executeDeferredReleases(currentFrameSlot);
finishActiveReadbacks(true); finishActiveReadbacks(true);
return QRhi::FrameOpSuccess; return QRhi::FrameOpSuccess;