0

I am trying to synchronize access to external memory across 2 processes on android vulkan, my system is telling me that it is only supporting

VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT

which can be exported as as copy, not as a reference.

What I am doing is this in process A ( exporting fd )

CALL_VK(vkQueueSubmit(queue, 1, &submit_info, fence));

int fd;
VkFenceGetFdInfoKHR getFdInfo{};
getFdInfo.sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR;
getFdInfo.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
getFdInfo.fence = fence;
CALL_VK(vkGetFenceFdKHR(device.device_, &getFdInfo, &fd));

and then this in process B ( importing copy of a payload from a fd)

VkImportFenceFdInfoKHR importFenceFdInfo{};
importFenceFdInfo.sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR;
importFenceFdInfo.handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
importFenceFdInfo.fd = fd;
importFenceFdInfo.fence = fence;
importFenceFdInfo.flags = VK_FENCE_IMPORT_TEMPORARY_BIT;

CALL_VK(vkImportFenceFdKHR(device.device_, &importFenceFdInfo));

The thing is if in the process B the fence I've got back is still unsignalled ( it was pending after vkQueueSubmit ) then since this is a copy and not a reference it will never be signalled and I will never know when my GPU runtime will have been finished. I am getting a freeze in the following call in my process B

VkResult result = vkWaitForFences(device, 1, &fence, VK_TRUE, -1);

Then what is the point in all this?

I am expecting that I shall be able to get the state of the fence updated in my process B once it is signalled by GPU.

  • 1
    Two questions for clarification: How do you arrive at the conclusion that this was a copy? By what method are you transferring the file descriptor (fd) to the other process? – datenwolf Nov 25 '22 at 15:03
  • Of this bit, the standard specifically says, "It owns a reference to the underlying synchronization primitive associated with the file descriptor." So maybe what's going on is not what you think is going on. – Nicol Bolas Nov 25 '22 at 15:30
  • https://vulkan.lunarg.com/doc/view/1.3.204.1/windows/1.3-extensions/vkspec.html Table 7. Handle Types Supported by VkImportFenceFdInfoKHR. It says SYNC_FD is a copy and temporal – Sergey Solovyev Nov 25 '22 at 15:53

2 Answers2

1

When you perform a fence import operation, that operation has a "transference" associated with it. Reference transference means that the fence you imported into is able to directly see the state of the fence payload at all times. If it waits on the fence to be signaled, then it will be woken up when that happens.

Copy transference means that it sees the state of the fence payload only at the moment the transfer happens. Any subsequent changes in the fence's payload are not available.

If it is your intent to have some process wait until a fence in a different process has completed, it cannot do this by performing a copy transference only once. It basically has to poll the other process through importing the fence, with each import seeing the payload state at the time of the polling.

And of course, you need to build in some system for the other process to know that the listening process has seen the signaling of the fence. Otherwise, the signaling process might reset the fence before the listening process has seen the signal.

Note that if an implementation restricts you to temporary, reference importation only, that represents a hardware limitation. So polling (along with listener protection) is the best the system allows. So Vulkan forces you to do it manually.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • "it basically has to poll the other process through importing the fence, with each import seeing the payload state at the time of the polling." I do not think this is true, because you can import fence from fd only once and then fd ownership goes back to vulkan implementation. – Sergey Solovyev Nov 25 '22 at 22:07
1

It seems that my problem was in how I transfer the fd to another process. I was simply using a piece of shared memory where I was storing to/reading from a fd. But this is incorrect, I need to import fd into a table of opened files in another process and seems like the only "approved" way for doing that is to send a socket message with SCM_RIGHTS type.

  • 1
    Ha, exactly that was my suspicion, why I asked for clarification on how you transfer the FD. On Unix FDs are just simple numbers, counting from one, and each process has its very own set of FDs and between processes there's going to be some significant overlap in FD numbers, yet those do refer to different things. – datenwolf Nov 26 '22 at 09:19