image
Одной из возможностей Parallels Desktop 12 для Mac является поддержка РС-игр. Существуют множество игр, доступных только для Windows и Xbox, и с помощью Parallels Desktop в эти игры можно играть на Mac без перезагрузки — внутри виртуальной машины. Можно ли считать, что проблема игр для PC на Mac полностью решена? Пока нет, но мы работаем над этим. В этой статье описаны несколько примеров того, как мы это делаем.

Почему сложно поддержать DirectX в полном объеме


На самом деле, виртуальная машина РС, позволяющая запускать Windows на Mac, сама по себе не гарантирует, что в ней будут работать PC-игры. Дело в том, что большинству игр требуется поддержка DirectX определенной версии со стороны видеоадаптера, и обеспечение этой поддержки полностью ложится на плечи разработчиков видеодрайверов. Естественно, что видеодрайвера, разработанные для «настоящих» видеокарт Nvidia, AMD и Intel, в виртуальной машине работать не будут.

На данный момент последней версией DirectX является DirectX 12, но она еще не получила широкого распространения. Другое дело — версия DirectX 11, уже достаточно популярная среди разработчиков игр. Правда, начиная с DirectX 10 существует — и активно применяется на практике — возможность работать с версией DirectX 11 и выше на видеокарте, поддерживающей, например, только DirectX 10, с ограничением функциональности, поэтому большинство новых игр, написанных для DirectX 11, могут работать на DirectX 10 без заметной визуальной разницы.



Мы обеспечиваем поддержку DirectX, начиная с самых первых версий Parallels Desktop для Mac. По мере эволюции Windows и DirectX, Parallels Desktop также развивался. Мы поддерживали DirectX 7, DirectX 8, DirectX 9, и уже несколько лет — и DirectX 10, что в свете вышеописанного особенно важно. Но та часть функциональности DirectX 10, которая касается работы видеодрайвера — правила, по которым надо трактовать его команды и создавать изображение — описана в документации довольно сжато. Количество разных комбинаций, состояний, вызовов — очень большое, и просто прочитать спецификацию, чтобы создать по ней однозначный программный код, которой позволит запускаться и работать любой PC-игре, к сожалению, нереально.

Кроме того, следует знать, что мы обеспечиваем поддержку DirectX 10 через OpenGL, т.е. преобразуем команды для DirectX в команды для OpenGL. Но одна и та же конструкция в OpenGL и в DirectX может работать несколько по-разному, и в разных условиях могут отрисовываться разные картинки. Что же остается? Остается работать методом проб и ошибок, т.е. запускать современные игры, которые пользуются функциональностью DirectX 10, и работать над ошибками.

Наша борьба с Overwatch


Проверить нашу поддержку DirectX 10 мы решили на примере игры Overwatch — многопользовательской «стрелялки», выпущенной компанией Blizzard Entertainment для всех основных игровых платформ, т.е. для PC, PS4 и Xbox One — но не для Mac. Игра Overwatch пользуется возможностями DirectX 10 очень интенсивно, поэтому она оказалась хорошим тестом на прочность для нашего DX10-драйвера. И игра заработала — но с множеством проблем. Многие вещи отрисовывались неправильно, медленно. Вот как выглядела игра поначалу.



Ниже мы опишем лишь три проблемы из тех, с которыми нам пришлось столкнуться.

Элементы управления и пункты меню


Первое, что бросилось нам в глаза — на видеокартах NVidia и Intel игра Overwatch не отрисовывала часть пунктов меню, индикаторов и значков. Проблему мы нашли довольно быстро — она оказалась связана с расхождением в трактовке значений встроенной переменной VertexID в вершинных шейдерах. В случае индексной отрисовки в DirectX эта переменная равна значению «индекса вершины», а в случае работы через OpenGL к нему еще прибавляется значение BaseVertex. Шейдеры, генерирующие текстуру, которая затем используется для отображения меню и других «плоских» элементов игры, используют в своем коде сравнение VertexID с предопределенными значениями. Поскольку драйверы для NVidia и Intel работают согласно спецификации OpenGL, они выдают неправильную картинку. Драйверы для AMD, напротив, не прибавляют BaseVertex к VertexID, в результате ошибка накладывается на ошибку и получается правильный результат.

Можно было бы легко исправить ситуацию с помощью расширения GL_ARB_shader_draw_parameters, но, к сожалению, Mac его не поддерживает — во всяком случае, пока. Мы нашли другое решение — когда используются видеокарты NVidia и Intel, мы передаем значение BaseVertex внутрь шейдера, и затем вычитаем его из gl_VertexId. В итоге получается значение переменной, корректное с точки зрения DirectX 10 числа. На видеокартах от AMD этого, естественно, не происходит.

Проблема с тенями


На самом деле тени объектов рисовались в Overwatch правильно. Зато на всех освещенных участках были заметны полоски.



После того, как мы детально разобрались с шейдерами, причина обнаружилась в настройке состояния OpenGL. Функция RasterizerState компонента Direct3D 10 Runtime имеет три значения, задающие корректировку глубины полигонов: DepthBias, DepthBiasClamp и SlopeScaledDepthBias. Их аналог в OpenGL сводится к вызову glPolygonOffset с правильными параметрами, и наша ошибка заключалась в том, что при нулевом значении DepthBias мы не предполагали, что SlopeScaledDepthBias может быть не равен нулю, поскольку считали, что корректировка глубины полигонов в этом случае выключена.

Отчего выпадают волосы


Тот факт, что все персонажи игры Overwatch под Parallels Desktop либо полностью потеряли свои шевелюры, либо постриглись «под ежик», вызвал бурную реакцию в социальных сетях и породил много шуток.



Однако стоит заметить, что «оттягиваясь» на полысевших героях, добродушно настроенные пользователи не заметили, что в игре отсутствуют не только волосы персонажей, но и некоторые другие объекты. Тестирование показало, что причина этой экзотической ошибки — в нехватке свободных текстурных каналов. В OpenGL их может быть не более 16 на каждый тип шейдера. Это ограничение было связано с тем, что использование текстурных каналов с номерами 16 и выше на видеокартах AMD приводит к порче состояния OpenGL в драйвере и проблемам в последующих отрисовках. В результате вместо всех остальных текстур, участвующих в отрисовке, шейдер получал черный цвет, что в ряде случаев приводило к полному пропаданию рисуемого объекта со сцены. Надо сказать, что от самой проблемы мы, конечно, не избавились, но поскольку в Overwatch негативный эффект от снятия данного ограничения оказался минимальным, мы решили для данного случая от него избавиться. Стоит отметить, что в общем случае проблема дефицита текстурных каналов в OpenGL по сравнению с DirectX 10 стоит остро, т.к. последний теоретически позволяет использовать до 128 ресурсов в одной отрисовке, и спасает только то, что приложений, пользующихся такой возможностью, довольно мало.

Результат


Вся работа заняла у нас меньше месяца, и исправив ошибки — как описанные, так и ряд других — мы добились того, что теперь наши пользователи действительно могут играть в Overwatch под Parallels Desktop для Mac, и эта игра работает в условиях виртуализации довольно быстро. Эта скорость, конечно, не сравнима со скоростью работы Overwatch на РС, и в случае серьезных нагрузок игра тормозит. Но цель «догнать и перегнать PC» нами и не ставилась. На примере Overwatch мы нашли проблемы в работе нашего виртуального драйвера и смогли их исправить. Полученные результаты помогут в поддержке работе других 3D-приложений. И, конечно, ничто не сравнится с положительной обратной связью от пользователей Mac — ведь теперь благодаря нам они могут играть на этой платформе в свои старые любимые игры, переносом которых на Mac уже никто и никогда бы не озадачился.



Когда же появится поддержка DirectX 11


Дело в том, что OpenGL на Mac'ах развивается медленно и всегда заметно отстает от последних актуальных версий. Даже для поддержки DirectX 10 нам зачастую не хватало имеющейся функциональности OpenGL на Mac, приходилось прибегать к различного рода ухищрениям и эмулировать недостающие возможности самостоятельно. Сейчас Mac поддерживает OpenGL 4.1 и этого кое-как хватает для DirectX 10, но для 11-ой версии недостает ряда ключевых возможностей, например, compute-шейдеров. Так что, многое зависит от того, будет ли Apple дальше развивать OpenGL на своих машинах.
Поделиться с друзьями
-->

Комментарии (15)


  1. NickSin
    20.09.2016 10:33
    +1

    Спасибо за статью! Мне всегда интересно читать про то, какие «костыли» приходятся пилить людям в рамках ограниченной функциональности платформы,


  1. Ogi
    20.09.2016 10:35
    +22

    У меня просто в голове не укладывается, как можно на техническом ресурсе, каковым является Хабр, брать картинку 1920?1080 в PNG весом в добрые 3,5 МБ, ужимать её средствами HTML до маленького прямоугольничка, при этом ещё и искажая пропорции, и помещать её до ката.


    1. Alaunquirie
      21.09.2016 00:11
      +3

      <irоny>Они и код также пишут, наверное… А потом герои лысые! :D</irоny>


    1. sindes255
      21.09.2016 17:55
      +2

      Вот скажите честно — что Вас заставило посмотреть размер картинки?


      1. Alaunquirie
        23.09.2016 12:14
        +1

        Небезлимитный трафик, например? Да и просто забота о ресурсах. Предвижу вопрос «у кого-то ещё не безлимит» и «а вам не всё равно»: давайте я 50-метровую гифку до ката в следующий пост вставлю, если уж «всем наплевать» и «у всех безлимит». Отлично будет грузиться.


  1. Rad1calDreamer
    20.09.2016 10:36
    -2

    valve под windows-то — периодически всех бреет

    ps — не могу картинку вставить почему-то


  1. rughost
    20.09.2016 10:55

    А что по системным требованиям?
    Есть мак мини 2012 года выпуска 2.5 GHz Intel Core i5 4Gb оперативы. В минималки для винды вроде вписывается.
    На маке же параллелс запускается туговато. Когда работаешь, винда чуть-чуть с запаздыванием реагирует.
    Что-то у меня сильные подозрения, что оверватч будет дико лагать. Вы на какой машине тестировали?


    1. voidMan
      20.09.2016 11:09

      Для этой игры главное видеокарта. Судя по описанной вами конфигурации даже в нативной винде в Bootcamp вам вряд ли будет комфортно в такой динамичной мультиплеерной игре.


    1. SmirkinDA
      20.09.2016 11:40
      +1

      На самом деле, игра Overwatch новая и рассчитана на современное и достаточно мощное железо (в особенности, видеокарты). А при запуске чего-либо в виртуальной машине, полезно придерживаться принципа «железо на Mac должно быть на ступень выше», т.е. если на такой же видеокарте на PC, например, игра работает очень хорошо, то внутри Parallels Desktop на Mac'е она, скорее всего, будет играбельна, но не более.


  1. eax32
    20.09.2016 12:35

    А транслировать в Metal например еще не пробовали? Как я понимаю сейчас Apple больше сосредоточен на нем, чем на OpenGL.


    1. SmirkinDA
      20.09.2016 12:50
      +2

      Да, Metal сейчас активно развивается, но, во-первых, это совсем другое API, переход на него потребует переписать большую часть нашего кода; во-вторых, даже в последних версиях для OS X Sierra в нем недостает функциональности по сравнению с OpenGL.


      1. NickSin
        24.09.2016 11:03

        Мне что-то подсказывает, что OpenGL они не будут развивать, а просто своё API Metal доделают и всё. Рано или поздно придётся переписывать код(


  1. Idot
    20.09.2016 18:57
    -1

    В OpenGL их может быть не более 16 на каждый тип шейдера. Это ограничение было связано с тем, что использование текстурных каналов с номерами 16 и выше на видеокартах AMD приводит к порче состояния OpenGL в драйвере и проблемам в последующих отрисовках.

    Можно подробнее? Во всех версиях OpenGL? А что с DirectX на AMD?


    1. SmirkinDA
      21.09.2016 11:13

      Этот параметр не зависит напрямую от версии OpenGL и задается в драйвере для конкретной видеокарты (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS). На современном железе на PC обычно поддерживается 32 текстуры на каждый шейдер, т.е. 96 для конструкции VS + GS + PS. Даже этого мало для DirectX 10+, где можно использовать до 128 ресурсов одновременно. На Mac'ах же до сих пор работает только по 16 текстур на шейдер, т.е. 48 в сумме, а на AMD в ряде случаев использование текстурных каналов с номерами выше 15-го приводит к порче состояния OpenGL и появлению ошибок в последующих отрисовках.


      1. Idot
        21.09.2016 13:38

        Спасибо!