Продолжаю шествие бесполезного навоза. В этот раз я понтуюсь своим функционалом отладки из движка, все так же на чистейший Vulkan + Rust.
Стоило давно это сделать, просто как-то не задумывался. Но в принципе, теперь у моего крейта есть отдельный движок, где можно все отлаживать. Зачем вам это нужно? Понятия не имею.
TL;DR: написал визуализатор для своего Vulkan-движка чтобы не сдохнуть от рендердока, потому что я конченный дебил.
Короче. Каждый раз когда у меня что-то ломалось в графике, я открывал рендердок, ждал пока он прожуёт 38^(10000мб) дамп, искал в нём один забытый барьер и закрывал рендердок. Потом это повторялось через час. В какой-то момент я просто сел и написал свой инструмент потому что всё равно быстрее.
Что есть сейчас.
- Граф кадра. Все ноды (passes, resources, submits) и связи между ними. Лейаут через Sugiyama чтобы 200 нод не превращались в кашу. Когда что-то добавляется или удаляется, граф плавно перестраивается, а не моргает.
- Sync DAG. Лайны очередей, бары сабмитов, детектор циклов и орфан-семафоров. Если compute ждёт graphics а graphics ждёт compute - я это вижу до того как получу смерть устройства.
- Память. Полоски VkDeviceMemory с цветными квадратиками аллокаций. Наводишь - видно вызовы, размер, возраст. Сверху бары по хипам. Утечку видно сразу, не надо ждать пока прод упадёт по OOM.
- Профилировщик пассов и жэпэу-таймлайном отдельно. Первый показывает сколько проц писал команды, второй настоящие гпу-таймстемпы. Раздельно потому что таймстемп-период это ад и без vkGetCalibratedTimestamps они не коррелируют, врать не буду.
- Валидация. Лог с фильтрами по серьезности (severity), поиском, автопрыжком на ошибку. Связан с графом - если варнинг про image layout, нода с этим имеджем подсвечивается красной точкой.
- Мониторинг канарейки (гуард бэндов). Интеграция с hardened allocator из моего крейта - читай hardened malloc из GrapheneOS, который я прикрутил к Vulkan. Когда что-то пишет за границы буфера, видно паттерн актуальных байт против ожидаемых, с подсветкой отличающихся. 0xCD - кто-то прочитал неинит, 0xDD - UAF, ASCII - строка улетела не туда. Полезно.
- Детерминизм. Таблица ранов с агрегатным хешем. Если десятый ран отличается от первых девяти - строка красная, кнопка открывает диф-битмапу с покрашенными в красное пикселями которые разошлись. Невидимые гонки атомиков становятся видимыми.
- Табы наверху, можно открывать несколько одинаковых, перетаскивать, пинить. Сохраняется между запусками. Скруббер для прокрутки назад на 16к последних событий, Ctrl+P замораживает поток. Снапшоттинг в файл - можно прислать кому-то и тот откроет, если не взорвется.
Архитектура примитивная до неприличия. Кольцевая память между моей либой и вьювером, 256 байт на запись, лоззи при переполнении. Продюсер пишет, вьювер читает. Падает один - другой ждёт.
- Рендер вообще без пайплайнов. CPU растеризатор пишет в BGRA буфер, потом vkCmdCopyBufferToImage в свопчейны. Никаких шейдеров, никаких VE внутри инструмента валидации.
Чего нет.
- Capture/replay отдельных кадров. Это рендердок, я туда не лезу.
- ГПУ-сталлинг на уровне волн. Это Nsight и RGP.
- Linux и macOS. Пока только винда, рендер платформонезависимый, но клей к отвратительным в реализации X11/Wayland не написан.
Хз, надо ли публиковать вообще, но если вдруг кому тут понадобится и кто точно такой же мазохист как и я - вылью на гх. А, нуида, все снова zero-dependency, кроме ash, разумеется, иначе с вулканом я там вообще не поработаю. А так... Ну, Win FFI)))
Если будете говорить что я переизобрёл <ээээээээнструмент> - я знаю, мне быстрее было написать чем учиться <эээээээээээнструменту>. Суп вилкой есть тоже можно.
*Да, Tracy я видел. Мне нужен был вулканоспецифичный аудит барьеров и трекинг дескрипторов, а не зоны таймлайна.