travisvroman/kohi

[BUG] Vulkan Sync Validation issues.

Opened this issue · 1 comments

Describe the bug
There are currently lots of sync issues occurring when Vulkan Sync validation is enabled.

To Reproduce
Steps to reproduce the behavior:

  1. Open Vulkan Configurator
  2. Check Validation Settings->Synchronization
  3. Check Validation Settings->Synchronization->QueueSubmit Synchronization
  4. UNcheck Limit Duplicated messages.
  5. Run Kohi testbed
  6. Observe errors. See attached example.

Expected behavior
No synchronization errors occur.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Windows 11, macOS Sonoma 14.5 (presumably all platforms)
  • Version 0.8.0

Additional context
See attached log

console.log

Some additional thoughts on this:

This seems to be primarily caused by the fact there is a single vertex/index buffer as opposed to one per frame-in-flight. This means that uploads/updates need to be handled differently, as updating the vertex/index buffer currently happens while it is still being used in the previous frame's command buffer execution.

While there are several ways around this, the ideal way would be to essentially upload to a completely new range of memory in the buffer (new offset and size) and hold off on deleting the old version's offset and size for at least a frame (maybe frames in flight - 1?). This would avoid having to have one vertex/index buffer per frame in flight as well as avoid the race condition currently present.

This could likely be accomplished by working in some additional logic:

  • A backend interface function to query the "frames in flight" from the backend. (only needed if this is done per frame in flight, not sure yet if this needs to be done)
  • An array (possibly one per frame-in-flight) that holds offsets of data to be freed in the free list.
  • A new "upload" function (i.e. b8 renderer_renderbuffer_upload(renderbuffer* buffer, u64 old_size, u64 new_size, u64* offset);:
    • For new uploads, provide the new_size as normal, but INVALID_ID_U64 for both old_size AND pointed-to-memory for the offset. This will perform an allocation under the hood and return the offset value in the pointed-to memory.
    • For re-uploads, provide the new_size as normal, but the current size in old_size and the current offset in the pointed-to-memory for offset. The buffer will then check the freelist to see if this block is currently allocated. If it is, it will mark that block (and its old_size) for deletion. If it's not allocated, write an error and do nothing (fail). The memory will then be deleted in an update pass in the next frame.
    • Convert any usage of allocate/load/free re-uploads to use this new function instead (i.e. sui_label_control).