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