venus: properly handle implicit fence from the compositor
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Vulkan is supposed to operate in explicit synchronization mode. However,
for legacy compositors that only support implicit fencing, we have to
extract the compositor implicit fence (release fence) and resolve it
properly. Since we used to rely on renderer side drivers being able to
handle implicit in-fence, here we only opt-in the new behavior for those
known to have issues with that.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34516>
This commit is contained in:
Yiwei Zhang 2025-05-17 10:28:38 -07:00 committed by Marge Bot
parent 5535184539
commit c093a4e18b

View file

@ -10,6 +10,9 @@
#include "vn_wsi.h"
#include <xf86drm.h>
#include "drm-uapi/dma-buf.h"
#include "vk_enum_to_str.h"
#include "wsi_common_entrypoints.h"
@ -273,6 +276,39 @@ vn_QueuePresentKHR(VkQueue _queue, const VkPresentInfoKHR *pPresentInfo)
return vn_result(dev->instance, result);
}
static int
vn_wsi_export_sync_file(struct vn_device *dev, struct vn_renderer_bo *bo)
{
/* Don't keep trying an IOCTL that doesn't exist. */
static bool no_dma_buf_sync_file = false;
if (no_dma_buf_sync_file)
return -1;
/* For simplicity, export dma-buf here and rely on the dma-buf sync file
* export api. On legacy kernels without the new uapi, for the record, we
* do have the fallback option to track the wsi bo in the sync payload and
* do DRM_IOCTL_VIRTGPU_WAIT where we do sync_wait.
*/
int dma_buf_fd = vn_renderer_bo_export_dma_buf(dev->renderer, bo);
if (dma_buf_fd < 0)
return -1;
struct dma_buf_export_sync_file export = {
.flags = DMA_BUF_SYNC_RW,
.fd = -1,
};
int ret = drmIoctl(dma_buf_fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &export);
close(dma_buf_fd);
if (ret && (errno == ENOTTY || errno == EBADF || errno == ENOSYS)) {
no_dma_buf_sync_file = true;
return -1;
}
return export.fd;
}
VkResult
vn_AcquireNextImage2KHR(VkDevice device,
const VkAcquireNextImageInfoKHR *pAcquireInfo,
@ -293,8 +329,24 @@ vn_AcquireNextImage2KHR(VkDevice device,
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
return vn_error(dev->instance, result);
/* XXX this relies on implicit sync */
/* Extract compositor implicit fence and resolve on the driver side upon
* the acquire fence being submitted. Since we used to rely on renderer
* side drivers being able to handle implicit in-fence, here we only opt-in
* the new behavior for those known to be unable to handle it.
*/
int sync_fd = -1;
if (dev->physical_device->renderer_driver_id ==
VK_DRIVER_ID_NVIDIA_PROPRIETARY) {
struct vn_image *wsi_img = vn_image_from_handle(
wsi_common_get_image(pAcquireInfo->swapchain, *pImageIndex));
assert(wsi_img->wsi.is_wsi);
struct vn_device_memory *wsi_mem = wsi_img->wsi.is_prime_blit_src
? wsi_img->wsi.blit_mem
: wsi_img->wsi.memory;
if (wsi_mem)
sync_fd = vn_wsi_export_sync_file(dev, wsi_mem->base_bo);
}
int sem_fd = -1, fence_fd = -1;
if (sync_fd >= 0) {