rhi: vulkan: fix crash when making readbacks in consecutive frames

When requesting a readback every frame, the readback activeFrameSlot
alternates between 0 and 1. Suppose we are in currentFrame 1, and
process a list of readbacks of slots [1, 0]. First, we skip the readback
of slot 0 since it does not match the currentFrame 1. The list thus
remains [1, 0]. Then, we process the readback of slot 1, and call
activeTextureReadbacks.removeLast(). This removes the readback of slot
0, while in reality we processed the readback of slot 1. The
activeTextureReadbacks is now [1], containing a readback for which we
called vmaDestroyBuffer(), leading to a crash ("double-free" attempt) in
Vulkan on the next function call.

To fix this, remove the readback that is actually processed (index i)
instead of the last one. Since we iterate backwards, indices remain
valid.

Pick-to: 6.8 6.9
Change-Id: Idd4296de45167edd0a9da345dcc1c3b6ac71a6d6
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Aurélien Brooke 2024-12-22 21:14:19 +01:00
parent 2f5b46731d
commit 73405890b8

View File

@ -4570,7 +4570,7 @@ void QRhiVulkan::finishActiveReadbacks(bool forced)
if (readback.result->completed) if (readback.result->completed)
completedCallbacks.append(readback.result->completed); completedCallbacks.append(readback.result->completed);
activeTextureReadbacks.removeLast(); activeTextureReadbacks.remove(i);
} }
} }
@ -4593,7 +4593,7 @@ void QRhiVulkan::finishActiveReadbacks(bool forced)
if (readback.result->completed) if (readback.result->completed)
completedCallbacks.append(readback.result->completed); completedCallbacks.append(readback.result->completed);
activeBufferReadbacks.removeLast(); activeBufferReadbacks.remove(i);
} }
} }