VK_KHR_display ve VK_EXT_direct_mode_display ile Vulkan'da doğrudan ekran taraması nasıl yapılır

Her pencere-sistemi yüzeyi (xcb, wayland, …) frame’lerinizi bir kompozitör üzerinden yönlendirir — en iyi ihtimalle fazladan bir kopya, en kötüsünde fazladan bir frame gecikmesi. VK_KHR_display hepsini atlar: GPU’nun kendi ekran kontrolcülerini ve plane’lerini numaralandırır ve tarama donanımına doğrudan sunarsınız. Dijital tabela, VR kompozitörleri ve kamera duvarlarının sıfır-kompozitör frame’leri böyle elde ettiği yöntem budur.

path.txt
normal:  app → swapchain → kompozitör → KMS → display
direkt:  app → swapchain ──────────────► KMS → display   (VK_KHR_display)

Ekranları ve modları numaralandırma

display.cpp
// Instance uzantıları: VK_KHR_surface, VK_KHR_display
// (+ Linux'ta VK_EXT_direct_mode_display, VK_EXT_acquire_drm_display)

uint32_t n = 0;
phys.getDisplayPropertiesKHR(&n, nullptr);
std::vector<vk::DisplayPropertiesKHR> dps(n);
phys.getDisplayPropertiesKHR(&n, dps.data());
// dp.display, dp.displayName, dp.physicalResolution,
// dp.physicalDimensions, dp.supportedTransforms,
// dp.planeReorderPossible, dp.persistentContent

vk::DisplayKHR display = dps[0].display;

phys.getDisplayModePropertiesKHR(display, &n, nullptr);
std::vector<vk::DisplayModePropertiesKHR> modes(n);
phys.getDisplayModePropertiesKHR(display, &n, modes.data());
// mode.parameters.visibleRegion + .refreshRate (mHz, örn. 59940)

// Plane'ler: donanım-içi kompozitör. Her ekran bir alt küme kullanır.
phys.getDisplayPlanePropertiesKHR(&n, nullptr);
std::vector<vk::DisplayPlanePropertiesKHR> planes(n);
phys.getDisplayPlanePropertiesKHR(&n, planes.data());
uint32_t planeIdx = findPlaneForDisplay(planes, display);

// Bu plane bu modla ne yapabilir?
vk::DisplayPlaneCapabilitiesKHR pcaps{};
phys.getDisplayPlaneCapabilitiesKHR(modes[0].displayMode,
                                    planeIdx, &pcaps);
// pcaps.supportedAlpha, .minSrcRect/maxSrcRect, .minDstRect/maxDstRect,
// pcaps.supportedDstPosition — plane görüntüyü
// her yere yerleştirebilir mi, yoksa sadece tüm modu kaplayan 0,0'da mı?

Yüzeyi oluşturma

surface.cpp
vk::DisplaySurfaceCreateInfoKHR sci{};
sci.displayMode     = modes[0].displayMode;
sci.planeIndex      = planeIdx;
sci.planeStackIndex = planes[planeIdx].currentStackIndex;
sci.transform       = vk::SurfaceTransformFlagBitsKHR::eIdentity;
sci.globalAlpha     = 1.0f;
sci.alphaMode       = vk::DisplayPlaneAlphaFlagBitsKHR::eOpaque;
sci.imageExtent     = modes[0].parameters.visibleRegion;

vk::UniqueSurfaceKHR surf = inst.createDisplayPlaneSurfaceKHRUnique(sci);
// Buradan: normal swapchain + present — doğrudan taramaya.

Linux’ta ekranı edinme

Ekran DRM’ye aittir — bir kompozitör veya getty tutuyorsa önce kontrolü almanız gerekir:

acquire.cpp
// VK_EXT_acquire_drm_display — açtığınız/kiraladığınız drm fd'yi Vulkan'a verin:
int drmFd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
// (veya logind/X'ten kiralanmış fd'de drmModeGetLease)
phys.acquireDrmDisplayEXT(drmFd, display);

// VK_EXT_direct_mode_display — çıkışta geri bırakın:
dev.releaseDisplayEXT(display);

VK_EXT_acquire_drm_display olmadan sadece kimsenin sahip olmadığı bir ekranı kullanabilirsiniz — sadece-framebuffer-konsolu olan bir makinede bu genelde “çalışır”, ama masaüstünde DRM lease yolunu (drmModeCreateLease) isteyeceksiniz.

Neden uğraşmalı

wins.txt
kompozitör kaldırıldı → -1 kopya veya -1 frame gecikme
öngörülebilir pacing  → kompozitör zamanlama jitter'ı yok
sadece tam ekran      → duvarlar, kiosk'lar, tabela, VR runtime'ları için mükemmel
plane kontrolü        → overlay'ler için alfa/konumlandırma donanımda

Pratik kurallar

  • VK_KHR_display özel kontrol verir — uygulamanız kompozitörün kendisidir: mod-ayarlama, güç durumları ve temizliği kendiniz halletmelisiniz (crash = yeniden edinilene kadar siyah ekran).
  • planeReorderPossible/supportedDstPosition kontrol edin: bazı plane’ler sadece tam-ekran — tek ekran plane’inde çok-pencereli düzen yapamazsınız.
  • alphaMode + planeStackIndex birden fazla yüzeyi tamamen donanımda istiflemenizi sağlar (UI overlay altında video) — her biri bir plane.
  • Tüm sürücüler desteklemez — NVIDIA + AMD/amdgpu DRM destekler; tasarlamadan önce vkEnumerateInstanceExtensionProperties ile VK_KHR_display kontrol edin. llvmpipe/lavapipe test için çalışır.
  • Gerçek uçtan-uca gecikme için VK_EXT_present_timing ile birleştirin — doğrudan taramada “sunulan” zaman damgası gerçek fotonlardır, kompozitörün kuyruk kabulü değil.

Check out similar posts by category: Vulkan C++