Valve и NVIDIA поделились опытом портирования Source Engine под Linux
На конференции разработчиков игр (Game Developers Conference – GDC), компании Valve и Nvidia выступили с докладом, посвящённым портированию игр под Linux. Презентация с данного мероприятия доступна на сайте Nvidia.
Наиболее интересные моменты:
- В качестве мотивов почему следует портировать игры на Linux, упоминаются:
- Открытость операционной системы Linux и экосистемы.
- Довольно быстрый рост популярности Linux в качестве игровой платформы.
- Логичный промежуточный шаг при портировании игр на мобильные платформы, где также доминируют стандарты семейства OpenGL
- Производительность.
- Под Linux официально доступен Steam.
- OpenGL предоставляет доступ к возможностям оборудования, оперируя при этом сугубо возможностями оборудования, а не версиями ОС или чем-либо ещё. В частности, в Китае в данный момент все ещё очень много пользователей с ОС семейства Windows XP, которые не могут пользоваться Direct3D 10/11. Тем не менее, при использовании OpenGL будут доступны полные возможности оборудования, в том числе и в данной версии ОС. Это позволит использовать возможности современного оборудования даже указанным пользователям.
- Публично доступные спецификации стандарта.
- Спецификации развиваются комитетом, в котором может принять участие любая заинтересованная сторона, для этого не требуются огромные суммы денег.
- OpenGL проще расширять, любой вендор может предложить свои расширения.
- OpenGL очень богат по своим возможностям.
- Для управления окнами настоятельно рекомендуют использовать SDL, относительно небольшую и кроссплатформенную библиотеку на Си. SDL берет на себя все что касается работы с окнами, независимо от ОС, в том числе и на мобильных платформах. Valve пользуется данной библиотекой при портировании своих проектов, что доказывает пригодность библиотеки для достаточно требовательных применений. Кроме того, основной разработчик libsdl в настоящее время работает в Valve.
- Проблемы с которыми столкнулись в Valve:
- Файловые системы в unix-подобных ОС по умолчанию чувствительны к регистру имён файлов, тогда как в Windows файловые системы по умолчанию игнорируют регистр. Для игр это, как правило, не является проблемой так как игровые ресурсы обычно поставляются в платформо-нейтральных контейнерах. Тем не менее, в процессе разработки это может быть проблемой. Наиболее простым решением является перевести имена всех ресурсов в нижний регистр.
- Ошибочные define’ы, например предполагающие, что на Linux может быть только выделенный игровой сервер и более ничего.
- Проблемы с локалью могут вызывать проблемы в функциях printf/scanf. Решение: установить локалью en_US.utf8, а локализацию предоставить самому приложению. Так как в некоторых случаях локаль en_US.utf8 в системе может отсутствовать, следует предусмотреть вывод предупреждения в данном случае.
- Шрифты: рекомендуется использовать библиотеки freetype и fontconfig. Тем не менее, может потребоваться пересчёт размера шрифтов.
- Использование RDTSC (прецизионный таймер, основанный на счётчике тактов современных CPU х86). Вместо него рекомендуется использовать вызов clock_gettime(CLOCK_MONOTONIC), не зависящий от архитектуры процессора.
- Использование raw mouse input, когда весь ввод мыши монопольно отправляется одной программе. Это очень хорошо работает для игр, однако некоторые оконные менеджеры при этом также перенаправляют и весь клавиатурный ввод. Это, в частности, может отключить работу alt-tab или аналогичных по смыслу горячих клавиш для переключения задач, что способно вызвать неудовольствие пользователей в некоторых ситуациях.
- Более шероховатая поддержка многомониторных конфигураций. Тем не менее, libsdl способна взять бОльшую часть проблем на себя.
- Инструментарий:
- Steam Linux Runtime и SDK предоставляют разработчикам игр ABI, не зависящий от дистрибутива.
- Компилирование и отладка:
- gcc – для компилирования.
- gdb – для отладки.
- cgdb – интерфейс на основе curses
- ldd – отслеживание зависимостей бинарного файла от библиотек (эквивалент dumpbin).
- nm – предоставляет информацию о символах, используемых программой.
- objdump – дизассемблер и инструмент для просмотра подробных деталей о бинарных файлах.
- readelf – инструмент для получения подробной информации об ELF файлах (основной формат исполняемых файлов в Linux).
- make – средство сборки проекта.
- Анализ производительности – CPU:
- perf – свободный профайлер под Linux, использующий performance counters современных процессоров
- vtune – инструмент от компании Intel, также существующий и в версии под Linux.
- Telemetry – многие коммерческие разработчики игр уже и так используют данный инструментарий.
- Примерное соответствие OpenGL и Direct3D:
- Direct3D 9 примерно соответствует возможностям OpenGL2. Начиная с этой версии доступны шейдеры.
- Direct3D 10 примерно соответствует семейству OpenGL3, появилось более актуальное API. Реализованы геометрические шейдеры.
- Direct3D 11 примерно соответствует OpenGL4. Поддержка тесселяции и произвольных вычислений на шейдерах.
- Ключевые отличия Direct3D от OpenGL с точки зрения разработчика:
- В OpenGL у потоков есть локальные данные, поэтому:
- У потока может быть только один текущий контекст.
- Контекст может являться текущим только для одного потока.
- Вызовы в OpenGL из потока без текущего контекста согласно спецификации не должны иметь никакого эффекта.
- OpenGL основан на Си. Объекты передаются хэндлами.
- Многие функции вообще не требуют указания хэндла и оперируют на выбранном в данный момент объекте.
- Как правило хэндл имеет тип GLuint.
- OpenGL поддерживает расширения.
- Несмотря на то что OpenGL довольно многословен и на первый взгляд требует больше вызовов, он показывает впечатляющую эффективность и производительность.
- В OpenGL отсуствуют проблемы с потерей устройств.
- В OpenGL у потоков есть локальные данные, поэтому:
- Расширения OpenGL:
- Есть специфичные для поставщиков расширения с префиксами NV|AMD|APPLE. Тем не менее, ряд из них был реализован сразу несколькими поставщиками. Например, NV_bindless_texture.
- Расширения с префиксом EXT реализуются сразу многими поставщиками. Например, EXT_separate_shader_objects
- Расширения с префиксом ARB были рассмотрены и приняты комитетом развивающим стандарт. Например, ARB_multitexture.
- Базовые расширения (Core extensions): базовые возможности из более поздних версий стандартов OpenGL представляются как расширения относительно прошлой версии стандарта.
- Есть зависящие от специфики платформы расширения: WGL, GLX, AGL и EGL.
- Советы разработчикам:
- Поиск в интернете имеет смысл делать как с префиксом GL_ или gl у соответствующего вызова так и без него.
- Чтение спецификаций стандарта себя оправдывает многократно.
- Если вам не нравится текущее направление развития OpenGL, присоединитесь к Khronos Group и постарайтесь оказать влияние на развитие стандарта. Лучше всего определять свое будущее самому.
- Core vs Compatibility: Некоторые производители утверждают что использование core-профайлов будет быстрее чем compat-, однако по факту подтверждение данного тезиса обнаружить не удалось. Поэтому можно пользоваться тем, что проще и удобнее конкретному разработчику. * Наиболее полезные расширения OpenGL по мнению разработчиков: EXT_direct_state_access, EXT_swap_interval (и EXT_swap_control_tear), ARB_debug_output, ARB_texture_storage и ARB_sampler_objects. Кроме того отмечаются NVX_gpu_memory_info и GL_ATI_meminfo позволяющие получить информацию о использовании памяти GPU.
- Самые проблематичные места в плане производительности:
- Вызов MakeCurrent очень дорогой. Следует избегать его вызова даже 1 раз на кадр.
- Современные драйвера как правило используют более 1 потока. Программа по факту взаимодействует с относительно тонкой прослойкой которая может распределять работу на несколько потоков. Некоторые вызовы заставляют производить полный сброс буферов и ресинхронизацию между потоками что сильно просаживает скорость операций.
- Наиболее проблемными оказались функции glGet() и glGetError() (вместо этой функции рекомендуется использовать ARB_debug_output)
Источник: phoronix.com