Intel/Vulkan: Image corruption upon layout transition of imported DRM PRIME framebuffer
System information
- OS: NAME=Chrome OS
- GPU: 00:02.0 VGA compatible controller [0300]: Intel Corporation Device [8086:9b41] (rev 02)
- Kernel version: Linux localhost 4.19.229-12876-gf06fecba2685 #1 SMP PREEMPT Wed Apr 13 19:44:12 PDT 2022 x86_64 Intel(R) Core(TM) i7-10610U CPU @ 1.80GHz GenuineIntel GNU/Linux
- Mesa version: Mesa 22.2.0-devel (git-ad864a7c)
Describe the issue
With DRM you can get a 'PRIME' handle pointing to the display framebuffer. This can be imported into Vulkan by means of the VK_KHR_external_memory
and VK_EXT_image_drm_format_modifier
extensions. When creating the Vulkan image, it is required to set the initial layout to UNDEFINED
. This implies that a layout transition is required in order to do anything with the image. However, if I perform any layout transition on the above device (e.g., UNDEFINED
to GENERAL
) then the framebuffer is badly corrupted (see photo below). I believe this is likely due to this device using framebuffer compression (I915_FORMAT_MOD_Y_TILED_CCS
). My main development machine is not using framebuffer compression (I915_FORMAT_MOD_X_TILED
) and does not exhibit this behaviour.
The fact that a layout transition is required in the first place strikes me as problematic. We don't own the memory, and DRM continues to use the buffer even while we have a handle to it. I'm not aware of any mechanism that could be used to safely synchronise writes with DRM. I'm not sure if this is an oversight in the Vulkan specification (perhaps it should be legal to import images with the GENERAL
layout), or if it is expected that the driver should be able to perform this transition without actually modifying the buffer.
For what it's worth, if I just don't do the layout transition, but continue to use the image as GENERAL
, everything seems to work ok. But the validation layer obviously doesn't like this, and I'd rather not rely on undefined behaviour like this.
See main.c for a minimal test case. This skips a few steps by making a few assumptions (only one Vulkan device, only one queue, only one memory type), but is sufficient to trigger the issue.
$ gcc -I/usr/include/libdrm main.c -l drm -l vulkan -o drm_vulkan_test
Sample output:
# VK_ICD_FILENAMES=/usr/local/cws/mesa/share/vulkan/icd.d/intel_icd.x86_64.json ./drm_vulkan_test
Failed to create /root/.cache for shader cache (Read-only file system)---disabling.
Device name: Intel(R) UHD Graphics (CML GT2)
Driver name: Intel open-source Mesa driver
Driver info: Mesa 22.2.0-devel (git-ad864a7c15)
DRM modifier: 100000000000004
Num planes: 2
Done