пятница, 25 марта 2022 г.
Мини блог
понедельник, 21 февраля 2022 г.
Как делается поддержка множества конфигураций железа
В DX большинство фич привязаны к версии API, а лимиты заданы константами в хэдере. В редких случаях есть параметры специфичные для железа, которые нужно запрашивать, но и они достаточно стандартизированы. К томуже количество конфигураций железа с поддержкой DX12 не так уж велико.
В Metal было несколько подходов, сначала был feature set, а потом его заменили на GPU family с Common/iOS/Mac семействами. Common задает общие фичи для всех конфигураций железа. Часть параметров также требуется запрашивать в рантайме. Сейчас свежее железо типа M1 и A14 имеет почти идентичные характеристики, что сильно упрощает разработку.
В Vulkan огромное количество фич и разнообразные лимиты, даже есть сайт, где можно посмотреть все конфиги: gpuinfo, также добавили слой device_simulation_layer, который частично эмулирует другие девайсы и упрощает тестирование.
воскресенье, 20 февраля 2022 г.
Особенности рендер пассов
Рендер пассы в Vulkan в основном нужны для оптимизации тайлового рендера в мобильных GPU (tile based deferred renderer), для этого в них используются сабпассы.
понедельник, 7 февраля 2022 г.
В чем проблема Vulkan on top of Metal
MoltenVk и некоторые другие проекты предоставляют возможность использовать Vulkan API поверх Apple Metal API, но внутри они содержат много неэффективного кода.
суббота, 5 февраля 2022 г.
Volume render, часть 4. Облака
пятница, 4 февраля 2022 г.
среда, 26 января 2022 г.
Vulkan device simulation layer
Не все знаю и умеют правильно использовать этот слой для тестирования движка на разных конфигах железа.
Главное - этот слой всего лишь меняет информацию, возвращаемую драйвером, на новую, определенную в json. Таким образом слой валидации сможет обнаружить ошибки в использовании констант и в работе с некогерентной памятью.
Детальное описание можно прочитать здесь.
Оптимизация очереди тасков
Пришло время оптимизировать очередь тасков для job/task system.
В идеале алгоритм выглядит так:
- Одна очередь на все потоки, чтобы таски, которые долго находятся в очереди смещались в ее начало и чаще проверялись на готовность к выполнению.
- Потоки захватывают небольшие диапазоны в очереди и проверяют таски в нем, потом блокируют следующий свободный участок.
- Таски с зависимостями добавляются в конец очереди, таски без зависимостей добавляются ближе к началу, так как могут быть вополнены сразу же.
пятница, 11 декабря 2020 г.
Генерация фигур
четверг, 30 июля 2020 г.
четверг, 23 июля 2020 г.
Volume render, часть 2. Оптимизация
понедельник, 6 июля 2020 г.
Профилирование шейдеров
воскресенье, 5 июля 2020 г.
среда, 1 июля 2020 г.
Crash reporting
суббота, 29 февраля 2020 г.
Job system
Какой требуется функционал:
- Зависимости между тасками - то есть таск запускается только когда все его зависимости завершились.
- Отмена тасков - до захвата таска потоком отмену обрабатывает сам планировщик, после - поток в котором выполняется таск.
- Слабые и сильные зависимости - определяет что будет при отмене зависимого таска. При слабой зависимости следующий таск запустится даже при отмене зависимого таска. При сильной зависимости следующий таск также отменяется.
- Кастомные зависимости - таким образом можно добавить зависимость между таском и GPU через VkFence, например.
- Совместимость с другими системами - работа с сетью также сделана на тасках, многопоточный ECS и рендер тоже будет на них и тд.
- Поддержка блокировок - для этого сделана отдельная зависимость InterlockDependency, куда передается callback, который может захватить мютекс или любой другой примитив синхронизации. Особенность в том, что захват идет через try_lock и если захватить не получилось, то таск остается в очереди до следующей проверки, если же получилось захватить, то таск отправляется на выполнение, а после выполнения вызывает функцию что бы разблокировать. Это позволяет не блокировать потоки при доступе к общим данным.
четверг, 13 февраля 2020 г.
Виртуальная машина для тестирования lock-free
Что обнаруживает виртуальная машина:
- Data race - параллельное чтение и запись в одну и ту же память.
- Пропущенные flush / invalidate cache, когда в другом потоке произошел flush, а в текущем читают без вызова invalidate. Либо когда в память произошла запись, но не вызвался flush.
воскресенье, 18 августа 2019 г.
Краткий обзор вулкан рендера в X4
Недавно вышел X4 Foundation, где только вулкан рендер. И реализация рендера оставляет желать лучшего.Даже рендердок не может долго дебажить, где-то портится память и все перестает работать. vktrace тоже не работает.
Выдает всего 30фпс в 4к даже в пустом космосе...
Недостатки:
- general layout для depth buffer
- барьер включают абсолютно все этапы (src = ALL_COMMANDS, dst = ALL_COMMANDS) и они даже не сгруппированы, то есть может подряд идти 2 таких барьера
- а еще у всех барьеров стоит флаг DEPENDENCY_BY_REGION, что не имеет смысла
- шейдеры с дебажной инфой и плохо оптимизированны
- очень много дескриптор сетов
- SSAO в полном разрешении, причем нужен только для кабины, где все статично, можно было запечь АО и сэкономить 3мс.
Краткий обзор вулкан рендера в UE4
vkAcquireNextImage вызывается в отдельном потоке и принимает fence, его ожидание происходит в потоке рендера, похоже это такой способ сделать двойную/тройную буферизацию.
- многопоточногого рендера нету.
- постоянно вызывается vkCmdResetQueryPool, хотя в пул записывается время, которое сбрасывать не требуется, а на трансфер очереди такое не будет работать.
- постоянно копируется время из пула в host-visible память, но я не знаю насколько это плохо, я бы все же сделал отложенное копирование.
- дескриптор сеты сбрасываются каждый кадр, что тратит время цпу и очень плохо для мобилок.
- очень много дескриптор пулов, что не рекомендуется делать, (366 пулов в демке с частицами)
- 5 сабмитов на кадр, причем все в конце кадра, это не очень хорошо, так как сабмиты тяжелые.
- для каждого сабмита создается фенс, который потом нигде не используется.
- много подряд идущих барьеров, неплохо было бы их сгруппировать.
- симуляция частиц идет в фрагментном шейдере, вот это интересно.
- пустой рендер пасс для очистки текстуры, как было в doom.
- есть dynamic offset для буферов, но смысла в них нет, так как дескриптор сет не переиспользуется.
Граф синхронизаций.
Сконвертированный из трейса код кадра.
Почему на мобилках не рекомендуют сбрасывать дескриптор пулы: pdf
суббота, 6 июля 2019 г.
VR эмулятор
вторник, 2 июля 2019 г.
Что спрашивают на собеседованиях в геймдев
Какой есть кэш и как работает, скорость доступа к памяти. Модели памяти weak vs strong.
Когда происходят кэш промахи.
Архитектура GPU
Как сгруппированы ядра: stream multiprocessor / compute unit, warp, какие особенности.
Как происходит растеризация, почему вытянутые треугольники это плохо (до перехода на tile based rendering).
Алгоритмы
Типичные вопросы по vector vs list, как работает map, unordered_map, что быстрее по сложности О и что лучше использует кэш. Как сделать быстрый поиск, как ускорить сортировку. Сложность алгоритмов.
Какие паттерны проектирования используются для оптимизации (ECS, DOD).
Алгоритмы рендеринга
Forward и deferred rendering, в чем различия, плюсы и минусы, какие оптимизации есть (tiled, clustered).
Physically based rendering в чем особенность, что такое BRDF, какие BRDF есть, в чем отличие.
Техники теней: shadow map, cascaded sm и тд. Фильтрация между каскадами.
Трассировка лучей: SSR, SDF shadows, volume rendering и тд.
Алгоритмы AA: supersampling, MSAA, MLAA, TAA и тд. Как сделать deferred shading с MSAA, как оптимизировать.
Многопоточность
Как получить deadlock. Какие примитивы синхронизации есть. Как работают атомики, что происходит с кэшем (надо расказать про memory order). Какая-нибудь задача на распараллеливание.
Математика
Векторное и скалярное произведение. Кватернионы. Как рассчитать OOBB. Как определить пересекается ли OOBB с frustum и как рассчитать экранные координаты. Задачи на геометрию.
C++
Вопросы про static, inline, virtual. Как работает виртуальная таблица, множественное наследование. Исключения. Move семантика. Плюсы и минусы стандартной библиотеки (stl).