На конференции разработчиков игр (Game Developers Conference - GDC), компании Valve и Nvidia выступили с докладом, посвященным портированию игр под Linux. Презентация с данного мероприятия доступна на сайте Nvidia.
Наиболее интересные моменты:
В качестве мотивов почему следует портировать игры на Linux, упоминаются:
Открытость операционной системы Linux и экосистемы.
Довольно быстрый рост популярности Linux в качестве игровой платформы.
Логичный промежуточный шаг при портировании игр на мобильные платформы, где также доминируют стандарты семейства OpenGL
Производительность.
Под Linux официально доступен Steam.
GL предоставляет доступ к возможностям оборудования, оперируя при этом сугубо возможностями оборудования, а не версиями ОС или чем-либо еще. В частности, в Китае в данный момент все еще очень много пользователей с ОС семейства Windows XP, которые не могут пользоваться DX10/11. Тем не менее, при использовании OpenGL будут доступны полные возможности оборудования, в том числе и в данной версии ОС. Это позволит использовать возможности современного оборудования даже указанным пользователям.
Публично доступные спецификации стандарта.
Спецификации развиваются комитетом, в котором может принять участие любая заинтересованная сторона, для этого не требуется огромные суммы денег.
GL проще расширять, любой вендор может предложить свои расширения.
GL очень богат по своим возможностям.
Для управления окнами настоятельно рекомендуют использовать 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 и DX:
DX9 примерно соответствует возможностям GL2. Начиная с этой версии доступны шейдеры.
SX10 примерно соответствует семейству GL3, появилось более актуальное API. Реализованы геометрические шейдеры.
DX11 примерно соответствует GL4. Поддержка тесселяции и произвольных вычислений на шейдерах.
Ключевые отличия DX от GL с точки зрения разработчика:
В GL у потоков есть локальные данные, поэтому:
У потока может быть только один текущий контекст.
Контекст может являться текущим только для одного потока.
Вызовы в GL из потока без текущего контекста согласно спецификации не должны иметь никакого эффекта.
GL основан на си. Объекты передаются хэндлами.
Многие функции вообще не требуют указания хэндла и оперируют на выбранном в данный момент объекте.
Как правило хэндл имеет тип GLuint.
GL поддерживает расширения.
Несмотря на то что GL довольно многословен и на первый взгляд требует больше вызовов, он показывает впечатляющую эффективность и производительность.
В OpenGL отсуствуют проблемы с потерей устройств.
Расширения OpenGL:
Есть специфичные для поставщиков расширения с префиксами NV|AMD|APPLE. Тем не менее, ряд из них был реализован сразу несколькими поставщиками. Например, NV_bindless_texture.
Расширения с префиксом EXT реализуются сразу многими поставщиками. Например, EXT_separate_shader_objects
Расширения с префиксом ARB были рассмотрены и приняты комитетом развивающим стандарт. Например, ARB_multitexture.
Базовые расширения (Core extensions): базовые возможности из более поздних версий стандартов GL представляются как расширения относительно прошлой версии стандарта.
Есть зависящие от специфики платформы расширения: WGL, GLX, AGL и EGL.
Советы разработчикам:
Поиск в интернете имеет смысл делать как с префиксом GL_ или gl у соответствующего вызова так и без него.
Чтение спецификаций стандарта себя оправдывает многократно.
Если вам не нравится текущее направление развития GL, присоединитесь к Khronos Group и постарайтесь оказать влияние на развитие стандарта. Лучше всего определять свое будущее самому.
Core vs Compatibility: Некоторые производители утверждают что использование core-профайлов будет быстрее чем compat-, однако по факту подтверждение данного тезиса обнаружить не удалось. Поэтому можно пользоваться тем, что проще и удобнее конкретному разработчику.
* Наиболее полезные расширения GL по мнению разработчиков:
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)
Наиболее интересные моменты:
В качестве мотивов почему следует портировать игры на Linux, упоминаются:
Открытость операционной системы Linux и экосистемы.
Довольно быстрый рост популярности Linux в качестве игровой платформы.
Логичный промежуточный шаг при портировании игр на мобильные платформы, где также доминируют стандарты семейства OpenGL
Производительность.
Под Linux официально доступен Steam.
GL предоставляет доступ к возможностям оборудования, оперируя при этом сугубо возможностями оборудования, а не версиями ОС или чем-либо еще. В частности, в Китае в данный момент все еще очень много пользователей с ОС семейства Windows XP, которые не могут пользоваться DX10/11. Тем не менее, при использовании OpenGL будут доступны полные возможности оборудования, в том числе и в данной версии ОС. Это позволит использовать возможности современного оборудования даже указанным пользователям.
Публично доступные спецификации стандарта.
Спецификации развиваются комитетом, в котором может принять участие любая заинтересованная сторона, для этого не требуется огромные суммы денег.
GL проще расширять, любой вендор может предложить свои расширения.
GL очень богат по своим возможностям.
Для управления окнами настоятельно рекомендуют использовать 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 и DX:
DX9 примерно соответствует возможностям GL2. Начиная с этой версии доступны шейдеры.
SX10 примерно соответствует семейству GL3, появилось более актуальное API. Реализованы геометрические шейдеры.
DX11 примерно соответствует GL4. Поддержка тесселяции и произвольных вычислений на шейдерах.
Ключевые отличия DX от GL с точки зрения разработчика:
В GL у потоков есть локальные данные, поэтому:
У потока может быть только один текущий контекст.
Контекст может являться текущим только для одного потока.
Вызовы в GL из потока без текущего контекста согласно спецификации не должны иметь никакого эффекта.
GL основан на си. Объекты передаются хэндлами.
Многие функции вообще не требуют указания хэндла и оперируют на выбранном в данный момент объекте.
Как правило хэндл имеет тип GLuint.
GL поддерживает расширения.
Несмотря на то что GL довольно многословен и на первый взгляд требует больше вызовов, он показывает впечатляющую эффективность и производительность.
В OpenGL отсуствуют проблемы с потерей устройств.
Расширения OpenGL:
Есть специфичные для поставщиков расширения с префиксами NV|AMD|APPLE. Тем не менее, ряд из них был реализован сразу несколькими поставщиками. Например, NV_bindless_texture.
Расширения с префиксом EXT реализуются сразу многими поставщиками. Например, EXT_separate_shader_objects
Расширения с префиксом ARB были рассмотрены и приняты комитетом развивающим стандарт. Например, ARB_multitexture.
Базовые расширения (Core extensions): базовые возможности из более поздних версий стандартов GL представляются как расширения относительно прошлой версии стандарта.
Есть зависящие от специфики платформы расширения: WGL, GLX, AGL и EGL.
Советы разработчикам:
Поиск в интернете имеет смысл делать как с префиксом GL_ или gl у соответствующего вызова так и без него.
Чтение спецификаций стандарта себя оправдывает многократно.
Если вам не нравится текущее направление развития GL, присоединитесь к Khronos Group и постарайтесь оказать влияние на развитие стандарта. Лучше всего определять свое будущее самому.
Core vs Compatibility: Некоторые производители утверждают что использование core-профайлов будет быстрее чем compat-, однако по факту подтверждение данного тезиса обнаружить не удалось. Поэтому можно пользоваться тем, что проще и удобнее конкретному разработчику.
* Наиболее полезные расширения GL по мнению разработчиков:
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)