Показаны сообщения с ярлыком FrameGraph. Показать все сообщения
Показаны сообщения с ярлыком FrameGraph. Показать все сообщения

среда, 11 мая 2022 г.

Нужен ли рендер граф? Часть 1

 Еще в 2018-ом я написал свой FrameGraph, который был моей первой попыткой упростить работу с Vulkan, за полгода активной разработки синхронизации и многопоточность были полностью переделаны 3 раза. В последней версии FG стал достаточно гибким, чтобы автоматически расставлять синхронизации внутри очереди, а с небольшими подсказками от пользователя мог расставлять синхронизации между очередями. Это отлично работает для прототипирования, но нужно ли для больших проектов?

среда, 9 января 2019 г.

FrameGraph. v0.6

  Сделал промежуточный релиз фреймграфа и конвертера трейсов.

  Главное достижение - я запустил трейс Doom на своем фреймграфе. Это было не то чтобы сложно, но были проблемные места. Например состояния, даже в вулкане они есть, это все вызовы vkCmdBind* и vkCmdSet*, при совместимых pipeline layout эти состояния сохраняются, при несовместимых инвалидируются, а мне нужно было получить все состояния для каждого DrawTask чтобы правильно его сконвертировать.
  Далее более специфичная проблема - нужно было выкинуть оригинальный staging buffer и заменить его на таски UpdateBuffer и UpdateImage, для этого приходилось обнаруживать копирование из staging buffer в device local buffer/image, потом искать где этот участок памяти записывается в staging buffer и уже его передавать в таски фреймграфа. Тут возникла ошибка, когда я сконвертировал все буферы в device local и получил до 9 000 вызовов копирования, что занимало более 50% времени CPU и немалое время на GPU.
  Возникли проблемы с сжатыми текстурами - у меня неправильно определялись диапазоны памяти и текстуры получались битыми. Еще обнаружился недостаток в рендерпассах - у меня не было поддержки readonly depth attachment и чтения текстуры в шейдере, для этого нужен был соответсвующий image layout, но проблема решилась достаточно быстро и я даже добавил это в тесты.
  Моя система кэширования для descriptor set не выдержала стресс теста и постоянно переполнялась, пришлось задавать всем буферам динамическое смещение, я не заметил влияния на производительность, зато теперь с учетом резерва достаточно всего 64-128 дескриптор сетов.
  Барьеры для текстур не проверяют диапазоны в 2D координатах, только слои и мипмэпы, поэтому например при копировании из staging buffer в текстуру вставляются лишние барьеры, но влияние на производительность я не заметил. Баг с излишним копированием в буферы позволил найти одно слабое место - расстановку барьеров для буферов, там учитываются все диапазоны и поиск пересечений может занять не мало времени. Решается это просто - большинство буферов судя по их usage - всегда readonly и только те что имеют usage staorage и transfer_dst могут измениться, соответственно только для них и расставляем барьеры.
  Сама идея использования vktrace для тестов оказалась не очень удачной, потому что трейс Doom может занимать 11-70Гб в зависимости от наполнености сцены и того, как долго записывается трейс. Это очень много, если 11Гб на первом запуске еще может закэшироваться в оперативной памяти и все последующие запуски не будут упираться в скорость чтения с диска, то 70Гб уже ни куда не помещается и получить больше 10-20fps нереально.
  Небольшие изменения в работе рендера связаные с переходом на фреймграф не оказали никакого влияния на время кадра, нужны более существенные изменения, чтобы как-то ускорить или замедлить рисование. Возможно я даже поэкспериментирую с оптимизацией, но это будет не скоро.
  

четверг, 30 августа 2018 г.

FrameGraph. часть 2

  Итак, первый этап разработки фреймграфа завершен, тесты написаны, картинка рисуется. Но похожих проектов уже несколько на гитхабе и намного больше в приватных репозиториях и в коммерческих проектах. Так как доказать, что мое решение лучше? А если не лучше, то как сделать его таковым?
  Нужны тесты на производительность. Но писать их долго, тем более нужно с чем-то сравнивать и желательно с чистым вызовами vulkan api, да еще с наилучшей оптимизацией. Это конечно весело, но хочется побыстрее получить результат, поэтому я стал искать другие варианты и нашел - слой vktrace позволяет записывать все вызовы vulkan api и потом проигрывать их заново. Остается только конвертировать сохраненный трейс в C++ код с вызовом чистого vulkan api и с вызовом FrameGraph api, таким образом можно за короткое время получить множество тестов на производительность и корректность рендеринга (сравнивая кадры), да еще и не на простых демках, а на реальных играх и приложениях.
  Подробнее о конвертере будет написано позже, сейчас идет только начальная стадия написания. В планах также добавить различные проходы оптимизации, что позволит увидеть потенциальный максимум производительности и сравнить его с текущим результатом, это будет полезно всем. Также хочу сравнить мой фреймграф с другими фреймворками и врапперами над вулканом, возможно сделаю opengl версию с максимальной оптимизацией, будет забавно сравнить фреймворки на вулкане с чистым opengl, особенно по нагрузке на cpu.

  Кроме тестов на производительность, которые только будут, уже готовы юнит тесты, в том числе на правильную расстановку барьеров (которую на данный момент не осилили в VEZ). Написан встроенный дебагер и сериализатор кадра, которые используются для тестирования расстановки барьеров в сложной сцене, тестирования сортировки графа, тестирования оптимизации рендер пассов и тд. При сериализации кадра происходит сортировка ресурсов по имени, а не по хэшу указателя, как они обычно хранятся в мапе, что делает описание кадра независимым от запуска программы (когда меняется seed для хэша например).
  Дополнительно дебагер обнаруживает возможные проблемы в при растановке барьеров, например ставятся подряд два барьера только на запись, это значит, что первый результат записи теряется, что скорее всего ошибка.

FrameGraph. часть 1

  Здесь будет рассказано о функциях фреймграфа: управление памятью, управление ресурсами, оптимизация кадра и тд.

FrameGraph. часть 0

  Начитался я презентаций от Dice, а также советов по оптимизации vulkan-рендерера, и захотел когда-нибудь написать свой фреймграф, и так уж получилось, что время на это нашлось...
  Для начала, что в моем представлении делает фреймграф - создает слой абстракции от низкоуровневого api (Vulkan, DX12), в отличие от различных graphics framework, фреймграф использует конкретный способ представления кадра - как набор узлов (задач), которые формируют граф. Такое представление кадра позволяет распараллелить некоторые задачи (раньше это не позволяло ни api, ни железо), оптимизировать память временных ресурсов, так как определены моменты начала и конца использования, наилучшим образом выставлять барьеры и тд.
  Первоначально я написал фреймграф на своем движке, реализация оказалось немного неудачной и, (так уж получилось) нашлось время на полное переделывание фреймграфа, на этот раз это будет отдельная либа с минимумом зависимостей и только на vulkan api, но абстракция позволяет добавить любое другое api. 

  Визуализация графа в программе GraphViz, это была не финальная реализация и тут отсутствуют некоторые связи между ресурсами. Зато хорошо видно как раставлены барьеры (маленькие узлы графа), разные типы узлов (красные - рисование, фиолетовые - копирование), видно как задачи отсортированы и некоторые из них могут выполняться параллельно.