properly fix transfer race conditions

This commit is contained in:
matthew 2025-07-20 11:46:51 +10:00
parent f02685c6b3
commit 6127a0bb70

View File

@ -707,12 +707,6 @@ ImmSubmit(Vulkan* vk, void delegate() fn)
success = VkCheck("ImmSubmit failure: vkQueueSubmit2 error", result); success = VkCheck("ImmSubmit failure: vkQueueSubmit2 error", result);
} }
if (success)
{
result = vkWaitForFences(vk.device, 1, &vk.imm_fence, true, 999999999);
success = VkCheck("ImmSubmit failure: vkWaitForFences post submission error", result);
}
return success; return success;
} }
@ -974,11 +968,20 @@ Transfer(T)(Vulkan* vk, Buffer* buf, T[] data)
bool bool
Transfer(Vulkan* vk, Buffer* buf, u8[] data) Transfer(Vulkan* vk, Buffer* buf, u8[] data)
{ {
bool success = true; bool success = TransferReady(vk);
u64 copied = 0; u64 copied = 0;
while(copied != data.length) while(copied != data.length && success)
{ {
if (copied != 0)
{
success = TransferReady(vk);
if (!success)
{
break;
}
}
u64 transfer_length = cast(u64)vk.transfer_buf.data.length; u64 transfer_length = cast(u64)vk.transfer_buf.data.length;
u64 data_length = cast(u64)data.length - copied; u64 data_length = cast(u64)data.length - copied;
u64 copy_length = transfer_length > data_length ? data_length : transfer_length; u64 copy_length = transfer_length > data_length ? data_length : transfer_length;
@ -1009,6 +1012,9 @@ Transfer(T)(Vulkan* vk, Buffer* buf, T* ptr)
{ {
assert(T.sizeof < vk.transfer_buf.data.length, "Transfer failure: structure size is too large"); assert(T.sizeof < vk.transfer_buf.data.length, "Transfer failure: structure size is too large");
bool success = TransferReady(vk);
if (success)
{
memcpy(vk.transfer_buf.data.ptr, ptr, T.sizeof); memcpy(vk.transfer_buf.data.ptr, ptr, T.sizeof);
auto fn = delegate() auto fn = delegate()
@ -1022,7 +1028,18 @@ Transfer(T)(Vulkan* vk, Buffer* buf, T* ptr)
vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, &copy); vkCmdCopyBuffer(vk.imm_cmd, vk.transfer_buf.buffer, buf.buffer, 1, &copy);
}; };
return ImmSubmit(vk, fn); success = ImmSubmit(vk, fn);
}
return success;
}
// Needs to be done before writing to the transfer buffer as otherwise it'll overwrite it while previous transfers are occurring
bool
TransferReady(Vulkan* vk)
{
VkResult result = vkWaitForFences(vk.device, 1, &vk.imm_fence, true, 999999999);
return VkCheck("Transfer failure: vkWaitForFences error", result);
} }
pragma(inline): bool pragma(inline): bool