VK_EXT_physical_device_drm açıklaması: VkPhysicalDevice'i bir DRM düğümüyle eşleştirme

Diyelim ki uygulamanız VA-API cihazını bulmak için /dev/dri/renderD*‘yi yokluyor, sonra Vulkan’da aynı GPU’yu seçmesi gerekiyor. Ancak VkPhysicalDevice‘in bir yolu yoktur — sadece bir ad ve bir LUID vardır. VK_EXT_physical_device_drm, her fiziksel cihazın DRM cihaz düğümlerini (/dev/dri/card*, /dev/dri/renderD*) açığa çıkarır, böylece eşleştirebilirsiniz.

Çözdüğü sorun

problem.txt
VA-API tarafı:  /dev/dri/renderD128   ← vaOpenDriver ile açıldı
Vulkan tarafı:  enumeratePhysicalDevices → "AMD Radeon Graphics (RADV)"
                                    → "llvmpipe"
                                    → "AMD Radeon Graphics (RADV)"  ← aynı ad!
hangisi renderD128?

İsimler çakışır (aynı GPU ailesi), UUID’ler düğüm başına değildir, PCI adresleri yeniden başlatmalarda kararlı değildir. DRM primary/render düğümü, çekirdeğin zaten kullandığı kanonik kimliktir.

Sorgu

match.cpp
vk::PhysicalDeviceDrmPropertiesEXT drm{};
auto props = phys.getProperties2(&drm);
// drm.hasPrimary, drm.hasRender,
// drm.primaryMajor/Minor, drm.renderMajor/Minor — çekirdeğin
//   /dev/dri/cardN ve /dev/dri/renderDN için (major,minor)'u

// FFmpeg'in açtığı cihazla eşleştir:
struct stat st{};
fstat(vaapiFd, &st);
if (major(st.st_rdev) == drm.renderMajor &&
    minor(st.st_rdev) == drm.renderMinor)
    chosenPhys = phys;   // bu VkPhysicalDevice renderD128'dir

Eşleştirme akışı

flow.txt
1. FFmpeg, vaapi_device üzerinde VAAPI açar → fd al → fstat → (maj,min)
2. enumeratePhysicalDevices → her biri için PhysicalDeviceDrmPropertiesEXT
3. renderMajor/renderMinor eşleşmesi → o fiziksel cihaz, GPU'sunda
   zaten VA-API context'i olandır — DMA-Buf import'u aynı cihazda,
   cihazlar arası kopya yok

Bu olmadan rastgele bir RADV cihazı seçersiniz — muhtemelen diğer GPU — ve DMA-Buf ya import edilemez ya da PCIe üzerinden gidip gelir.

Uç durumlar

  • hasRender=false — cihazın yalnızca bir primary düğümü var (bazı yalnızca ekran GPU’ları); bunun yerine primaryMajor/Minor ile eşleştirin.
  • NVIDIA proprietary + nouveau farklı düğümler sunar — iki sürücü de bağlıysa aynı fiziksel kart iki kez görünebilir.
  • DRM düğümü olmayan bir cihaz (lavapipe) hasRender=false, hasPrimary=false raporlar — bu bir “eşleşme yok” durumudur, hata değildir.

Pratik kurallar

  • VK_EXT_physical_device_drm bir cihaz özellik uzantısıdır — instance oluştururken etkinleştirin, getProperties2 ile sorgulayın.
  • hasRender olduğunda her zaman renderMajor/Minor‘ı tercih edin — render düğümleri compute/decode API’lerinin (VAAPI, OpenCL) açtığıdır.
  • INI’nizdeki bir vaapi_device anahtarı fstat hedefi olur — kamera duvarı başına sabitleyin, otomatik seçmeyin.
  • Eşleşme boot başınadır — düğüm numaraları yeniden başlatmalarda kararlı değildir; kararlı bir INI değeri için /dev/dri/by-path/ symlink’lerini kullanın.
  • Eşleşmezse fallback hâlâ doğrudur: import başarısız olur, av_hwframe_transfer_data + staging yolu devreye girer (önceki yazılardaki zarif düşüş).

Check out similar posts by category: Vulkan C++ Linux