Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upsafely destroying semaphore used with WSI #152
Comments
|
However this is resolved, support in the validation layers is needed. One of the factors motivating creation of this issue is that I don't see how to add this to the validation layer without first clarifying when it is safe to destroy the semaphores pointed to by vkQueuePresentKHR's pWaitSemaphores. |
|
I think the formalism to describe it is mostly there since the synchronization descriptions overhaul. Some final touches in #785. |
|
Yea, I do somewhat keep finding loopholes and ambiguities. What worries me most is this spec quote:
(Same for Semaphore and Fence.) It marks any other queue commands that are not I had some time to collect my thoughts making the PR, and I think the (hopefully complete) behavior loosely based my current spec interpretation is (while necesserily making some stuff up):
Does that make sense? I welcome any notes. It also feels awfully complex. I wonder if I am overthinking it, and there is a room to make this much simpler. I am also waiting on some input from Khronos, because I assume too much stuff about the behavior, and some things need official resolution. |
In the above (emphasis mine) statement, I don't think the bold portion is true. DeviceWaitIdle does not cover the pending work that signals the semaphore, because that work happens external to Vulkan. It is presentation engine work. Hence, the only way to ensure the semaphore is idle is to first wait on it. After that, the usual synchronization logic falls out naturally because at that point, you have work related to the semaphore enqueued on a well-defined device queue. From my understanding, the rest of the assertions in the above comment are correct. |
|
@cubanismo If that is so, I feel it should be made an exception. The obvious expectiation of |
|
Think about how WSI would be/is implemented. It's essentially an under-the-covers external object situation. If you had a semaphore shared between two VkDevice objects, potentially in separate processes, would you expect calling vkDeviceWaitIdle() on one of those devices to idle any pending operations on the semaphore happening on the other device? That would be an impossible implementation requirement. The caveat with this line of thinking is that in such a case, there would be two OS-level references to the semaphore payload, so you could safely destroy one instance of the semaphore without idling the other. This gets fuzzy with AcquireNextImage. It essentially binds the specified semaphore to an opaquely-defined semaphore payload whose lifetime is not discussed in the spec as far as I can tell. Without examining our driver more closely, I'm not even sure what I can say about our implementation's behavior if the device were destroyed while operations on such semaphores are pending. This ambiguity is unfortunate, but it doesn't change the awkwardness of asking the driver to idle things happening outside of the scope of its queues. |
|
@cubanismo No, I would expect only the device that user asked to be stopped to be stopped. I mean, you are talking about implementation details. You could say the same about Anyway, I am gonna make an Issue (#1059) as it seems to be a separate can of worms that actually might impact compatibility. |
This issue seeks clarification on when it is safe to destroy a semaphore that has been used by WSI functions vkAcquireNextImageKHR and vkQueuePresentKHR.
A separate issue in the layer repo will address the validation layer detecting when a semaphore used by these functions is destroyed too soon. (I plan to edit this text with a cross-reference after the layer issue has been filed.)
vkAcquireNextImage's semaphore is used to establish or extend a dependency chain with a write-after-read hazard ensuring that the acquired image is modified only after the presentation engine is done reading from the image.
Quoting from the spec:
and
This seems to fully defines when vkAcquireNextImageKHR's semaphore may be destroyed. I think it says that semaphore may be destroyed after completion of all queue operations that include semaphore in the pWaitSemaphores list for the queue submission. But that destroying it any sooner results in undefined behavior. In other words, one must track completion of all consumers of semaphore to know when it is safe to destroy semaphore.
For the validation layer to detect an application destroying vkAcquireNextImageKHR's semaphore too soon, I think the burden is no different than for other semaphores that are not used by vkAcquireNextImageKHR.
Switching to vkQueuePresentKHR, pPresentInfo->pWaitSemaphores extends a dependency chain with a read-after-write hazard ensuring that the images are presented only after writes to the images have completed.
Quoting from the spec:
and
Comparing these two excerpts there might be an issue here with the specific spec language of "present request" and "present operation". I'm addressing that separately within Khronos. I will assume that vkQueuePresentKHR is the present request, and that the present operation is carried out by the presentation engine after the present request schedules on the present operation on the presentation engine's own queue. (The presentation engine's queue is separate from the VkQueue.)
The spec excerpts do not seem to fully define when the semaphores pointed to by pWaitSemaphores may be destroyed. It is my interpretation of both the spec language and the intent of the spec that a non-blocking vkQueuePresentKHR request may schedule a present operation on the presentation engine's queue such that the present operation on the presentation engine's queue has a read-after-write hazard on pWaitSemaphores. This would mean that pWaitSemaphores may not be destroyed until after the presentation engine has completed the present operation.
However there seems to be nothing in vkQueuePresentKHR to indicate to the app when the presentation engine has completed the present operation. The next-best thing is to assume that pWaitSemaphires may be destroyed after the swapchain is destroyed, or after a future vkAcquireNextImageKHR returns the same image. The latter imposes a book-keeping requirement on the application that is non-obvious and that had not occurred to me before now.
It might be possible to assume the semaphores may be destroyed after vkAcquireNextImageKHR returns some number of other images. How many? I don't see language in the spec in support of such an assumption. I'm not even entirely certain that the spec supports the earlier assumption of "the same image".
Finally, the purpose of this issue is to feel out and document discussion related to clarifying the spec language defining when the application may destroy the semaphores pointed to by vkQueuePresentKHR's pWaitSemaphores. If the existing spec language already covers this adequately that's fine, and this issue can document that interpretation.