EGL import via EGL_EXT_image_dma_buf_import_modifiers ignores explicit stride -> causes image distortion in VirtIO-GPU Venus

Summary

When using Vulkan inside a QEMU/KVM virtual machine via the VirtIO-GPU venus driver with an NVIDIA host GPU, the image appears distorted. After extensive debugging on the virglrenderer/mesa side, the venus maintainer (Yiwei Zhang) has pointed to an NVIDIA-side issue.

According to his findings, the NVIDIA EGL driver appears to ignore the explicitly provided stride (EGL_DMA_BUF_PLANE0_PITCH_EXT) when importing a DMA-BUF via EGL_EXT_image_dma_buf_import_modifiers with DRM_FORMAT_MOD_LINEAR. The client must pack the linear image with 32 bytes alignment (what NV EGL driver assumes) to avoid the distortion issue.

See the following bug report: virglrenderer#651 and specifically this comment.

Environment

  • Host GPU: NVIDIA GeForce RTX 5090

  • Host driver version: 595.45.04

  • Host kernel: 6.19.9

  • Host OS: Arch Linux

  • QEMU version: 11.0.0.rc0 (latest git)

  • virglrenderer version: 1.3.0 (latest git)

  • Guest OS: CachyOS

  • Guest Mesa version: 26.0.99 (latest git)

The bug also appears when using the latest stable versions of qemu, virglrenderer and guest mesa.

Steps to reproduce

  1. Set up a QEMU/KVM virtual machine with VirtIO-GPU Venus enabled:
    -device virtio-gpu-gl,hostmem=4G,blob=true,venus=true
    
  2. Install vulkan-virtio (or equivalent package) in the guest.
  3. In the guest, run: vkcube --wsi xcb --width 500 --height 500
  4. Observe diagonal distortion in the rendered image.
  5. Run: vkcube --wsi xcb --width 512 --height 512. Observe the image renders correctly.

Workaround

Changing WSI_PRIME_LINEAR_STRIDE_ALIGN from 256 to 32 in src/vulkan/wsi/wsi_common_drm.c and then recompiling guest Mesa eliminates the distortion. Probably because the the NVIDIA EGL driver is also using 32-byte stride alignment internally rather than honoring the provided pitch (?)