vkQueueSubmit kilitlendiğinde veya vkGetFenceStatus hiç
ateşlenmediğinde soru hangi komutun takıldığıdır. Shader printf
yardım etmez — GPU oraya hiç ulaşmadı. Breadcrumb’lar farklı çözer:
her command buffer çalışırken bilinen bir buffer’a marker yazar;
hang’den sonra son yazılan marker GPU’nun tam olarak nerede durduğunu
söyler. İki vendor uzantısı sağlar: VK_AMD_buffer_marker ve
VK_NV_device_diagnostic_checkpoints.
VK_AMD_buffer_marker — pipeline noktasında değer yaz
marker.cpp
// hang'i atlatan host-visible buffer:
// buf = VkBuffer + HOST_VISIBLE|COHERENT bellek, bir kez map'lenmiş
vkCmdWriteBufferMarkerAMD(cmd,
vk::PipelineStageFlagBits::eAllCommands, // ne zaman yazılacağı
markerBuf, offset, /*marker*/ frameTag);
// → pipeline bu cmd buffer'da bu stage'e ulaştığında,
// 'frameTag' markerBuf'a iner — CPU'ya anında görünür
Draw/dispatch’ler arasına serpin; inen son marker = tamamlanan son stage. Hang’ler kendini ele verir.
VK_NV_device_diagnostic_checkpoints — otomatik checkpoint’ler
checkpoint.cpp
// komut kaydı sırasında — app-görünür yazım gerekmez:
vkCmdSetCheckpointNV(cmd, (const void*)myTag); // tag = void* / int
// submit tarafında (veya timeout'tan sonra):
uint32_t n = 0;
dev.getQueueCheckpointDataNV(queue, &n, nullptr);
std::vector<vk::CheckpointDataNV> cps(n);
dev.getQueueCheckpointDataNV(queue, &n, cps.data());
// her entry: {stage, pCheckpointMarker} — queue'nun
// *her checkpoint'li submission için* son ulaştığı stage
getQueueCheckpointDataNV anahtar çağrıdır — GPU’nun geçtiği
checkpoint’leri stage mask ile geri okur. pipelineStage‘i
ayarladığınızla eşleşen son entry öldüğü yerdir.
Yine de çöktüğünde
crash.txt
breadcrumb'lı hang: yazılan son marker = tamamlanan son stage —
hang *sonraki* komuttadır
crash → DEVICE_LOST: kalıcı-map'li buffer'daki breadcrumb'lar bazı
sürücülerde device loss'u atlatır —
fault callback ateşlendikten sonra okuyun
ikisi: VK_EXT_device_fault (DEVICE_LOST yazısı) ile
birleştirip tam otopsi yapınPratik tarif
watchdog.cpp
// marker halkası, uçuşta olan her submission için bir:
struct Breadcrumb { uint64_t tag; uint64_t stage; };
// map'li buffer, kalıcı:
auto* crumbs = (Breadcrumb*)dev.mapMemory(mem, 0, size);
cmd.writeBufferMarkerAMD(eBottomOfPipe, buf,
offsetof(Breadcrumb,stage), myTag);
// … draw'lar …
cmd.writeBufferMarkerAMD(eBottomOfPipe, buf,
offsetof(Breadcrumb,tag), myTag);
// sonra bir watchdog thread'inde:
while (true) {
if (fenceTimedOut && crumbs[last].tag != expected)
logHang(crumbs[last]); // tamamlanan son stage = suçlu
}Pratik kurallar
VK_AMD_buffer_markeryalnızca AMD;VK_NV_device_diagnostic_checkpointsyalnızca NVIDIA — iki kod yolu veya genel bir wrapper istersiniz.- Marker buffer
HOST_VISIBLE+HOST_COHERENTolmalı ki GPU hang’deyken CPU okuyabilsin — DEVICE_LOCAL writeback işe yaramaz. eBottomOfPipe/eAllCommandsstage kullanın ki marker ancak önceki iş gerçekten bittiğinde flush olsun — erken bir stage ilerleme hakkında yalan söyler.vkCmdSetCheckpointNV‘nin tag’i hamvoid*‘dir — tag → “N’inci submit edilen command buffer, draw i” eşleme tablosu tutun ki fault yerini çözebilesiniz.- Gerçek bir GPU crash’i (hang değil) için
VK_EXT_device_fault+VK_NV_device_diagnostic_checkpointskombinasyondur — fault adresi, breadcrumb’lar komutu verir.
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow