DirectX 12 — доступ к играм нового уровня
В ходе конференции GDC 2014, которая состоялась 20 марта, был анонсирован DirectX 12. Основой DirectX 12 является ядро Direct3D, поскольку именно на нем создаются самые важные компоненты любых современных игровых приложений. Так, команда разработчиков сделала ряд изменений в Direct3D, результат которых — повышение эффективности и скорости большинства графических операций. Такие изменения позволят делать сцены игр более детальными и достигать максимального использования возможностей современных GPU. Стоит отметить, что такие возможности будут не только в самых новых игровых компьютерах, поскольку Direct3D 12 способен работать на любых устройствах от Microsoft. Теперь использование API Direct3D 12 возможно на телефонах, ноутбуках, планшетах, десктопах и Xbox One.
Но что же делает Direct3D 12 качественно лучше, чем его предшественники? Самое главное нововведение — это снижение уровня абстрагирования оборудования, что позволяет значительно улучшить в играх уровень использования GPU и масштабируемость. Также игры непременно получат значительное улучшение от объектов состояния конвейера и таблиц дескрипторов. Второе, но не менее важное улучшение, — это вхождение в Direct3D набора качественно новых возможностей для конвейера рендера. Они способны в несколько раз увеличить эффективность определения коллизий, расчетов прозрачности и геометрической отбраковки. Конечно же, API хорошо исключительно тогда, когда существуют необходимые инструменты для его эффективного использования. Также DirectX 12 будет прекрасно работать на ряде уже существующих видеокартах.
Тест 3DMark
Если вы являетесь геймером, то точно знаете о 3DMark — прекрасном инструменте, которые необходим для правильной оценки производительности в огромном спектре «железа» и устройств. 3DMark работает на Direct3D 11. Тест позволяет пользоваться поточным масштабированием. К сожалению из-за некоторых незначительных накладок, которые связаны с драйверами и рантаймом, при тестировании присутствует холостое время ожидания ядер и потоков. А после полного переноса 3DMark на новый Direct3D 12 в глаза сразу бросаются значительные улучшения:
- 50% прирост к утилизации CPU;
- улучшение распределения работы среди потоков.
Стоит отметить, что полученные цифры взяты из коммерческих игр а скриншоты сделаны на реальных приложениях с реализацией рантайма и драйверов Direct3D 12.
Консольная эффективность на персональном компьютере
Forza Motorsport 5 Tech Demo — это прекрасный пример игры, которая способна выжать максимум из известной консоли. На борту Forza имеет низкоуровневый API, взаимодействующий с графической подсистемой XboxOne. Известно, что такой уровень эффективности можно достичь исключительно на унифицированном «железе». Сегодня такая возможность появилась как на ПК, так и на смартфоне. В процессе переноса кода графического ядра, который базируется на Direct3D 11.1, команда программистов Turn 10 добилась не менее высокого уровня оптимизации для ПК благодаря широким возможностям, которые предоставляет Direct3D 12.
Откуда берется такая производительность? Ответ на этот вопрос достаточно прост: разработчики Direct3D 12 отказались от устаревшей модели программирования, которой пользовались при создании Direct3D 11, тем самым значительно «приблизив приложение к железу». Они пересмотрели огромное количество областей API, главными из которых являются специальные механизмы методы отправки заданий, представления состояний конвейера и доступ к разным ресурсам.
Direct3D11 посредством достаточно большого набора перекрестных объектов позволяет легко манипулировать различными состояниями конвейера. Например, состояниями пиксельного шейдера, выходного смесителя, входного ассемблера, растеризатора, которые могут в любой момент быть независимо друг от друга изменены. Этот механизм достаточно удобен для представления графического конвейера, но, к сожалению, он достаточно плохо «ложится» на новое «железо». Главная причина этого — существование взаимозависимости между разного рода состояниями. Например, ряд GPU способны комбинировать состояния выходного смесителя и пиксельного шейдера в одно аппаратное представление. При этом API Direct3D 11 позволяет менять состояние каждого из них независимо, но драйвер устройства не может это разрешить, пока не будет команды, что поточное состояние завешено, а это, в свою очередь, невозможно до начала «рисования». Все это приводит разным по времени задержкам при установке состояний «железа», подразумевает издержки и значительно меньшее количество вызовов «рисования» в каждом кадре.
Direct3D 12 решает эту проблему, унифицировав большую часть состояния конвейера в объект состояния конвейера, который неизменяем (ОСК). Он фиксируется непосредственно после его создания. Такое превращение позволяет драйверу и «железу» сразу же трансформировать ОСК в необходимые аппаратные инструкции для выполнения задач GPU. Также есть возможность динамического выбора, какой именно ОСК нужно использовать в текущий момент. После этого остается просто произвести копирование в аппаратные регистры маленького количества заранее просчитанного состояния, вместо того, чтобы вычислять аппаратное состояния «походу». Это все ведет к значительному уменьшению объема накладных расходов, возникающих между вызовами «рисования» и большему количество вызовов «рисования» в каждом кадре.
Списки команд и пакеты
В Direct3D 11 все задания отправляются при помощи одного ряда команд, которые поступают в GPU. Для процесса многопоточного масштабирования производительности игрового приложения применяют так называемые отложенные контексты. К сожалению, как и в случае ОСК, такие отложенные контексты абсолютно не соответствуют реальному положению дел в «железе».
Direct3D 12 — это воплощение новой модели отправки заданий, которая базируется на специальных списках команд, которые содержат всю нужную для исполнения в GPU информацию. В такие списки команд входят буферные и текстурные ресурсы, ОСК, аргументы для команды «рисования». Такой список команд является автономным и абсолютно не содержит состояния, вот почему драйвер заранее просчитывает нужные GPU команды, которые идут в независимом потоке. В этом процессе необходима только сериализация в финальной стадии отправки списка команд в GPU. Такая сериализация производится посредством очереди определенных команд.
Как дополнение списков команд, Direct3D 12 имеет механизм вторичного предварительного вычисления, который использует специальные пакеты, а также предусматривают повторное использование. Например, если игровому приложению нужно отобразить 2 модели персонажей, которые имеют разные текстуры, то существуют 2 подхода:
- Записать список команд, содержащий 2 набора идентичных вызовов «рисования»;
- Записать один пакет, при помощи которого произойдет «рисование» 1-го персонажа; потом будет выполнена «перемотки назад» данного пакета дважды внутри списка команд (при этом будут использованы разные типы ресурсов).
Во втором случае драйверу нужно просчитать необходимые инструкции только 1 раз, при этом создание списка команд будет равно 2-м вызовам функций, которая имеет низкую стоимость.
Таблицы и дескрипторы
Direct3D 11 имеет достаточно удобную привязку ресурсов, но при этом ряд возможностей современного оборудования не используется. Игровое приложение создает и привязывает специальные объекты-«представления» к определенным слотам на разных «уровнях» шейдера в конвейере. Шейдеры же считывают данные из слотов, которые являются фиксированными в момент «рисования». Такая модель значит, что если игровому приложению нужно сделать «рисование», воспользовавшись другим набором ресурсов, то нужно осуществить повторную привязку объекта-«представления» к совершенно другим слотам и опять вызывать «рисование». Это опять таки создает накладные расходы, которые устраняются при полном использовании возможностей современного «железа».
Direct3D 12 способен заменяет модель привязки, тем самым значительно увеличивая производительность. Он не требует привязки к слотам и автономных ресурсных представлений, при этом Direct3D 12 дает кучу дескрипторов, посредством которых игровое приложение создает собственные представления ресурсов. Такой принцип работы позволяет GPU авансом и напрямую производить запись аппаратного представления описания нужного ресурса непосредственно в память. Для декларации используемого в конвеере ресурса, игра дает одну или несколько дескрипторных таблиц, представляющих из себя субдиапазон кучи дескрипторов. Поскольку такая куча ранее была загружена нужными определенными данными, то изменение данной таблицы дескрипторов — это очень дешевая операция.
Также, как дополнение к таблицам и дескрипторной куче, Direct3D 12 динамически индексирует ресурсы в шейдерах, что позволяет применять новые техники рендера.Все это позволяет финализировать сцену содержащую, например, 1000 материалов так же быстро как и сцену содержащую 10 материалов.