все что нужно знать о directx 12
Зачем нужен DirectX 12 в Windows 10
Для обычного игрока разработка компьютерных программ может показаться сложным и длительным процессом. И это действительно так. Например, каждая модель консолей (Xbox, PlayStation, Nintendo) содержит в себе один конкретный процессор, видеокарту, встроенную память, слоты ввода и другие аппаратные компоненты. Поэтому для них не требуется дополнительное ПО.
В то же время разработчики компьютерных игр сталкиваются с большим изобилием аппаратных конфигураций. Как следствие, возникает необходимость в приложении, способном заставить весь этот “зоопарк” работать слаженно и без ошибок.
Содержание статьи:
Что такое DirectX в Windows 10
Простыми словами, DirectX это программное обеспечение, взаимодействующее с аппаратными компонентами ПК. Оно участвует в вычислительных процессах, связанных с рендерингом 2D и 3D графики, рендеринге видео и воспроизведении звука на платформе Windows.
Комментарий NVIDIA: Основное внимание DirectX 12 направлено на значительное увеличение качества графики за счет снижения нагрузки на центральный процессор.
Приложение яростно соперничает с OpenGL, другим графически ориентированным софтом, представленным в 1992 году. Он представляется с открытым исходным кодом и находится в непрерывной разработке технологического консорциума Khronos Group. И хотя OpenGL является кросс-платформенным API, он вряд ли когда-либо станет конкурентом для DirectX в Windows.
Преимущества DirectX 12
Вплоть до выхода DirectX 12, недостатком программы было отсутствие низкоуровневого доступа к аппаратным компонентам компьютера. Для решения этой проблемы AMD выпустили свой собственный пакет, под названием Mantle API. Это помогло оптимизировать работу старых версий DirectX с аппаратурой AMD. Тем не менее, данный софт никак не повлиял на владельцев видеокарт NVIDIA.
Исторически сложилось так, что драйверы и программное обеспечение ОС управляли памятью и другими ресурсами ПК отдельно от имени их разработчиков. Однако это было неэффективно. Низкая производительность связана в первую очередь с тем, что данный алгоритм не мог проанализировать потребности активной программы. DirectX 12 в свою очередь помогает приложениям напрямую управлять ресурсами компьютера и выполнять синхронизацией аппаратуры. В результате разработчики игр могут наладить эффективную работу GPU относительно других компонентов.
Дополнительной особенностью DirectX 12 является функция распределения нагрузки между ядрами центрального процессора. Если раньше, в DirectX 11, “отдуваться за всех” могло лишь одно ядро, то теперь задействованы все элементы ЦП.
Частые вопросы о DirectX
Как определить версию DirectX
Часто на DirectX не обращают такого же внимания, как оно уделяется версии драйвера видеокарты или любого другого устройства. Это вполне естественно. И по этой причине многие пользователи не знают какая версия программного обеспечения у них установлена. К счастью, уточнить ее довольно легко.
1. Воспользуйтесь комбинацией клавиш Windows + R и откройте утилиту Выполнить.
2. Введите команду dxdiag и нажмите Enter.
3. Перед вами появится окно под названием Средство диагностики DirectX.
4. Обратите внимание на раздел Сведения о системе и найдите в нем пункт Версия DirectX.
При желании, вы можете экспортировать найденную информацию в текстовый файл, щелкнув по клавише Сохранить все сведения.
Почему установлен DirectX 11.2, а не DirectX 12
Частый вопрос. В некоторых случаях даже при наличии Windows 10 у пользователей отображается версия установленного DirectX — 11.2 или даже ниже. Причины тому две:
Как обновить DirectX
Если вы владелец современной видеокарты, но “Средство диагностики DirectX” оповещает о наличии старой версии программы, существует два способа решить проблема. Первый — скачать DirectX 12 с сайта Microsoft, второй — провести обновление Windows 10.
Как обновить систему:
1. Откройте Параметры Windows с помощью комбинации клавиш Windows + I.
2. Откройте раздел Обновление и безопасность.
3. Перейдите в Центр обновления Windows и щелкните по клавише Проверить наличие обновлений.
4. Дождитесь завершения обновления операционной системы.
Как только скачается и установится последнее обновление, перезапустите компьютер, чтобы внесенные изменения вступили в силу. Затем проверьте обновился ли DirectX до последней версии.
Нужно ли настраивать приложение DirectX
DirectX 12 не является привычной нам программой с “экзешником”, которую можно запустить и настроить под собственные нужны. Она всегда работает в фоновом режиме с дефолтными параметрами. Грубо говоря, DirectX — это средство коммуникации между вашими программами и железом.
Проблемы при установке DirectX 12
Ошибки в работе DirectX случаются крайне редко. Тем не менее, вы можете столкнуться с двумя проблемами:
Чтобы избежать первой проблемы, достаточно скачать DirectX 12 с официального сайта — с сайта Microsoft. Сторонние ресурсы могут поставлять такие файлы или битыми или же с вирусами. Поэтому лучше всего загружать их с проверенных источников.
Для решения второй потребуется воспользоваться командной строкой.
1. Откройте командную строку от имени администратора.
2. Введите команду chkdsk и нажмите клавишу Enter.
3. Дождитесь завершения сканирования.
4. В разделе Этап 1 найдите пункт Обработано поврежденных файловых записей. Если его значение равно 0, значит ошибок не найдено. Если же значение равно 1 или выше, продолжите выполнение инструкции.
5. Введите команду chkdsk /f и нажмите Enter. Утилита автоматически восстановит поврежденные файлы.
В некоторых случаях, после ввода команды chkdsk /f, вы можете получить следующее сообщение:
Согласитесь на повторный запуск восстановительного процесса после перезапуска компьютера.
Иногда даже незаметное программное обеспечение может быть ключом к согласованной работе всех установленных комплектующих. Своевременная диагностика проблем с DirectX поможет вам избежать ряда неприятных последствий, таких как, например, краша или сбоев приложений.
Надеемся, статья оказалась для вас полезной и помогла узнать что-то новое о DirectX 12.
Похожие статьи про восстановление данных:
Как создать пакетный файл BAT для выполнения в командной строке CMD
Batch (.bat) файл — это инструмент, который сэкономит вам не один десяток часов рабоч.
Значение компьютерных характеристик
Для многих пользователей задача разобраться с компьютерными характеристиками может показаться сложно.
20 способов ускорить Windows 10
DirectX 12 — от Леонардо да Винчи к современному искусству
Компьютерная графика — обширная и быстроразвивающаяся дисциплина. С каждым годом интерфейсы прикладного программирования становятся более гибкими, что позволяет на их основе реализовывать более сложные алгоритмы формирования и обработки изображений. Однако возможности интерактивной графики не достигли уровня пакетов 3d-моделирования и визуализации. Все это подталкивает к активным исследованиям в данной области.
DirectX 12 — компонент интерфейса программирования высокопроизводительной графики. Основные цели нового интерфейса — снижение CPU-оверхеда драйвера, понижение уровня абстрагирования оборудования, возможность объединения графических карт на уровне API (до этого существовали только vender-specific решения CrossFireX, NVIDIA SLI). Официально выпущен Microsoft в июле 2015.
Статья рассчитана на тех, кто уже работал с графическими библиотеками (OpenGL, DirectX 11). Однако для людей, которые планирует начать изучение графики именно с 12 версии возможно тоже будет полезной.
В ней мы рассмотрим следующие темы:
Окружение
DirectX 12 является частью Windows SDK в Windows 10. В качестве IDE используем Visual Studio, язык программирования C++. Для работы с DirectX, необходимо подключить хедеры d3d12.h dxgi1_6.h и библиотеки d3d12.lib, dxguid.lib, dxgi.lib, d3dcompiler.lib. Все это лежит в стандартных каталогах Windows SDK. Так же распространяется «D3D12 Helper Library» в виде одного заголовочного файла d3dx12.h, она позволяет сократить количество boilerplate кода. Его можно просто скачать по адресу d3dx12.h и вложить в проект.
Краткое описание графического пайплайна
В основе графической библиотеки лежат функции рисования, которые запускают графический конвейер — программно-аппаратное средство визуализации трехмерной графики. Аппаратная составляющая представлена видеоадаптером, программная — драйвером. Графический конвейер можно представить в виде черного ящика, разделенного на этапы и выполняющего необходимые преобразования. Содержимое этого черного ящика может быть различным. Выполняемые преобразования зависят от назначения графической системы, стоимости, требуемого уровня универсальности и многих других факторов. Также, конкретный видеоадаптер — сложный механизм, правила работы которого зачастую известны лишь непосредственно производителю.
Итак, на сегодняшний день процесс визуализации трехмерной сцены выглядит в общих чертах следующим образом.
Преобразование вершин
Каждая вершина имеет определенный набор атрибутов таких, как позиция, цвет, текстурные координаты, вектор нормали или все векторы из касательного пространства и, возможно, некоторые другие. Трансформация вершин — это первая стадия графического конвейера. На этом этапе входными данными являются атрибуты конкретной вершины, над которыми производятся математические преобразования. Эти операции включают трансформацию позиции вершины, генерацию и преобразование текстурных координат, расчет освещения для каждой отдельной вершины, а также любые другие операции, которые необходимо выполнить на уровне вершин. Каждая вершина обрабатывается параллельно с другими вершинами на доступных ядрах графического ускорителя. Основной результат вершинной программы — преобразовать координаты из модельного пространства в специальное пространство отсечения (clip space).
Построение примитивов и растеризация
Входные данные этого этапа — трансформированные вершины, а также информация о их соединении. Из этих данных осуществляется сборка геометрических примитивов. В результате получается последовательность треугольников, линий или точек. Над этими примитивами может производиться отсечение плоскостям, определенными в программе. Также на этом этапе могут быть отброшены задние треугольники объектов. Определяются эти треугольники по направлению обхода вершин (по часовой стрелке или против). Какое направление обхода соответствует заднему треугольнику задается через графическое API. Полигоны, прошедшие отсечение, могут растеризироваться.
Текстурирование и окрашивание
Над атрибутами примитивов, растеризированных в набор фрагментов, на этой стадии проводится необходимая интерполяция, а также последовательность математических преобразований и операций текстурирования, что определяет конечный цвет каждого фрагмента. Также на этом этапе может определяться новая глубина или даже исключение фрагмента из буфера кадра.
Пофрагментные операции
На этом этапе проводится ряд пофрагментных тестов, таких как тест отсечения (scissor test), тест трафарета (stencil test) и тест глубины (depth test). Эти тесты определяют конечный вид, цвет и глубину фрагмента перед обновлением экранного буфера. Если какой-либо тест проходит с ошибкой, то фрагмент не обновляется. После тестов выполняется операция смешивания, которая комбинирует финальный цвет фрагмента с текущим цветом пиксела, а итоговый результат записывается в экранный буфер. Операция смешивания выполняется на этом этапе, поскольку стадия текстурирования и окрашивания не имеют доступа к экранному буферу.
Более детальное устройство конвейера можно посмотреть в спецификации DirectX 11 (документ по DiretcX 12 затрагивает лишь изменения с предыдущей версией)
Новые возможности DirectX 12
Мы переходим от теоретической части непосредственно к описанию конкретных возможностей DirectX 12.
Состояния
В 11 версии программистам известны различные функции изменения состояний графического ускорителя: RSSetState(), OMSetDepthStencilState(), OMSetBlendState(). Оказалось, что такой подход плохо ложится на оборудование. В конечном итоге драйвер устанавливает адаптеру одно монолитное состояние, а отдельные вызовы или некоторые комбинации состояний могли приводить к непредсказуемым задержкам со стороны драйвера. В новой версии инженеры переосмыслили этот подход и исключили атомарное изменений состояний, теперь они объединены в одно — PSO (Pipeline State Object). Такое нововведение кажется более удобным со стороны пользователя: теперь не нужно беспокоиться о «висячих состояниях», которые остались с прошлых проходов. Более того, для лучшей эффективности установки, теперь дополнительно требуется передавать информацию о всех прикрепленных ресурсах в шейдер через Root Signature (об этом ниже).
Команды
В ранних версиях пользователи отправляли команды через так называемый immideate context. Под капотом создавались отложенные командные очереди и по мере заполнения отправлялись оборудованию. Необходимо отметить, что в DirectX 11 существует возможность создания deferred context. В DirectX 12 immideate context был исключен и deferred концепция стала основной. Теперь программист должен заполнить deferred command list, и в необходимый момент отправить его на исполнение.
Таким образом, реализация двойной и тройной буферизаций теперь выглядит более явно: создаются соответствующее количество command list, как только они заполнены, CPU переходит в режим ожидания свободного листа.
Здесь же стоит упомянуть о ресурсах, которые прикреплены к конкретному командному листу. Теперь удаление ресурса, использующегося на GPU, ведет к непредсказуемым последствиям. Например, раньше легально было выполнить Release() для текстуры которая еще используются — драйвер автоматически отследит, когда ресурс перестанет использоваться и только после этого удалит его.
Синхронизация
Для возможности отслеживания работы GPU, DirectX 12 предоставляет концепцию fence, которая инкапсулирована объектом ID3D12Fence интерфейсом. Fence — это целое число, которое представляет выполненную работу GPU на текущий момент. Сначала происходит эмитинг следующего «свободного» значения, вызывая ID3D12CommandQueue::Signal() в командной очереди. Затем с помощью ID3D12Fence::SetEventOnCompletion(UINT64 Value, HANDLE hEvent) происходит ассоциирование значения с примитивом winapi event. Теперь поток с помощью WaitForSingleObject() над подготовленным event-ом может приостановить выполнение до момента выполнения всей работы, предшествующий контрольному значению. Как только вся работа на GPU выполнится, значение в fence обновится, вызов WaitForSingleObject() разблокируется и поток продолжит выполнение.
Прикрепление ресурсов
Биндинг ресурсов в шейдер — одна из самых запутанных тем современного DirectX.
Обзор
В DirectX 11 использовалась следующая модель биндинга: каждый ресурс устанавливался в шейдер соответствующим вызовом API. Например, для установки двух текстур (если не задумываться о семплерах) в 5 и 6 слоты пиксельного шейдера применялся следующий код:
Где GetShaderResourceView() возвращает указатель на объект типа ID3D11ShaderResourceView.
В шейдере затем текстуры использовались так:
Такая система достаточно удобная со стороны программиста, но с точки зрения графического ускорителя нет. Допустим, нам необходимо прикрепить текстуру на чтение в шейдере. Как должна быть передана информация о текстуре? Если мы заглянем в документацию GCN ISA, найдем следующий параграф:
All vector memory operations use an image resource constant (T#) that is a 128- or 256-bit value in SGPRs. This constant is sent to the texture cache when the instruction is executed. This constant defines the address, data format, and characteristics of the surface in memory.
Это означает, что для того чтобы описать текстуру, нам нужен этот небольшой дескриптор (128 или 256-битный), который нужно поместить в любое место памяти. Если мы прочтем остальную часть документации, мы заметим, что этот же шаблон также используется для всех других типов ресурсов. Фактически, когда дело доходит до доступа к ресурсу, понятие «слот» бессмысленно. Графический адаптер оперирует дескрипторами: текстуры (T#), сэмплера (S#) или константы (V#). С Direct3D 12 эти дескрипторы, наконец, отображаются непосредственно на дескрипторы оборудования — некоторая память GPU.
Дескрипторы
Сейчас ресурсы не прикрепляются в графический пайплайн прямо через вызовы методов, прикрепление происходит опосредовано через дескрипторы. Дескриптор — небольшой кусочек памяти, который содержит информацию о ресурсе (GPU виртуальный адрес, и, например, количество мипов, формат). Множество дескрипторов хранятся в дескрипторной куче — это просто массив дескрипторов фиксированного размера. Дескрипторные кучи могут содержать информацию о разных типах ресурсов:
CBVs, UAVs, SRVs могут содержаться в одной дескрипторной куче, а описания семплеров — в отдельной. Это разделение выражает тот факт, что семплеры в ускорителе обрабатываются отдельно.
Выше мы упомянули так называемые shader visible ресурсы. Соответственно, существуют non shader visible ресурсы:
Такие views ресурсов предназначаются только для прикрепления ресурса в пайплан (но не для использования в шейдере), и поэтому их нужно создавать в отдельной non shader visible дескрипторной куче (это задается флагом D3D12_DESCRIPTOR_HEAP_FLAGS::D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE при создании кучи).
Есть еще одна группа view’s, для которых дескрипторы (и, соответственно, дескрипторная куча) не требуются:
Представлены типами D3D12_INDEX_BUFFER_VIEW и D3D12_VERTEX_BUFFER_VIEW соответственно. То есть описания индексных и вершинных буферов содержатся в указанных выше структурах и затем передаются напрямую в Pipeline State Object. Вся память в PSO автоматически версионируется драйвером.
Таким образом, теперь вместо создания множества объектов типа ID3D11. View, мы создаем дескрипторы в дескрипторной куче.
Root signature
Root signature — объект DirectX 12 API который задает соответствие лэйаута дескрипторов и данных в слоты шейдера. Это, в некотором смысле, действительно сигнатура шейдера только с точки зрения использования ресурсов. Root signature не содержит конкретных дескрипторов и данных, она лишь задает лэйаут (устройство) дескрипторов, которые биндятся уже позднее на этапе рендеринга.
Root signature состоит из массив записей, которые называются root parameter. Действительные данные root parameter устанавливаются в рантайме и называются root arguments. Меняя root argument, меняются данные которые читает шейдер. Root parameter бывают трех типов:
Максимальный размер root signature — 64 DWORDs. Типы отсортированы по возрастанию уровня косвенности доступа ресурса в шейдере, но по убыванию возможностей.
Root constant это встроенное в root signature 32-битное значение, которое используется в шейдере как constant buffer. Предназначается для наиболее активно изменяющихся констант (например, MVP матрицы), но имеет жесткие ограничения на максимальный размер (всего поместится 4 матрицы). Так же такие данные доступны в шейдере с нулевым уровнем косвенности, и имеют более быстрый доступ чем все остальные способы. Полностью версионируются драйвером: их можно «установить и забыть».
Приложение может поместить дескрипторы напрямую в root signature во избежании хранения дескрипторов в куче дескрипторов — это второй способ inline descriptors. Пример таких данных — константа per object. Таким образом, не нужно беспокоиться о свободном месте в куче дескрипторов. Имеет первый уровень косвенности. Версионируется сам дескриптор (то есть описание ресурса), но ресурс который описывает этот дескриптор должен быть доступен до завершения его использования на GPU. Установка конкретных данных производится, например, методом ID3D12GraphicsCommandList::SetGraphicsRootConstantBufferView, в него передается индекс root parameter нашего inline descriptor и виртуальный адрес буфера.
Мы подошли к третьему, основному и универсальному способу прикрепления ресурсов. Таблица дескрипторов содержит массив descriptor range. Descriptor range — описание непрерывной цепочки дескрипторов определенного типа. Описание одной записи в таблицы дескрипторов проще показать кодом:
Видим, что RangeType — указывает тип дескриптора, NumDescriptors — количество, BaseShaderRegister — номер регистра внутри шейдера. Остальные параметры служат для расширенной настройки и пока не будем их рассматривать. В рантайме дескрипторы устанавливаются методом ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable, в него передается индекс root parameter нашей таблицы дескрипторов и первый дескриптор. Все дескрипторы, указанные в описании таблицы дескрипторов, подхватываются автоматически. Из этого следует, что они должны располагаться непрерывно друг за другом в descriptor heap.
Заключение
Мы рассмотрели некоторые возможности DirectX 12. Если вам интересная данная тема или любая другая из области компьютерной графики, отписывайтесь в комментариях.
DirectX 11 против DirectX 12: практическая польза от новой версии графического API
Оглавление
Немного теории
Для начала повторим вкратце основы о DirectX 12 из всего того, что мы рассказывали вам в своих многочисленных обзорах. Графические API обновляются довольно редко, и до сих пор большинство игр использует еще Direct3D 11 (D3D11 для краткости), которому уже больше 10 лет. Но все чаще игровые разработчики начинают использовать Direct3D 12 и Vulkan, которые появились после активного продвижения собственного API Mantle компанией AMD. Указанные API используют схожий подход по улучшению эффективности использования графических процессоров, но являются универсальными для всех современных GPU. В рамках сегодняшнего обзора мы не будем рассматривать Vulkan, но в целом этот API очень схож с D3D12 в своей основе.
Увы, при всех преимуществах новой версии DirectX, темп освоения новых возможностей разработчиками не так высок, как бы всем хотелось. До сих пор чаще всего используется DirectX 11 в виде основного API, и лишь при поддержке производителей GPU (в основном — AMD, по понятным причинам) они все же продавливаются в игры. Сначала поддержка Direct3D 12 во многих играх появлялась в экспериментальном виде, как проба пера, и частенько она не давала прироста производительности вообще, или он был крайне незначительный.
Если попытаться очень вкратце описать преимущества нового API, то главные его нововведения заключаются в асинхронных вычислениях, о которых мы поговорим ниже, и сниженной нагрузке на CPU из-за более быстрой подготовки вызовов функций отрисовки draw calls (команды, результатом которых является отрисовка полигональной сетки с соответствующими атрибутами). Каждый объект и персонаж в кадре требует исполнения нескольких таких функций отрисовки, и при большом их количестве в D3D11 довольно сильно загружается работой центральный процессор системы.
Кое-какую работу по оптимизации этой работы делает видеодрайвер (и у Nvidia он весьма эффективен, а вот D3D11-драйвер AMD справляется с оптимизацией похуже), но в любом случае, более быстрая подготовка вызовов draw calls в D3D12 может значительно снизить загрузку CPU и время простоя GPU, и в результате мы получим более высокую частоту кадров или возможность отрисовки большего количества геометрии при прочих равных. Многопоточная оптимизация для CPU в условиях D3D12 также работает куда более эффективно.
Так происходит потому, что прослойка API при управлении работой графического процессора в D3D12 стала значительно тоньше, и определенная работа была переложена с API на игровой движок, в том числе и менеджмент ресурсов. С одной стороны, это улучшает возможности по оптимизации производительности под конкретные запросы игры, с другой — увеличивает требования к знаниям и способностям игровых программистов. В случае D3D12 им приходится заниматься широким кругом задач, которыми они с D3D11 вообще не занимались. Учет особенностей разных графических архитектур и менеджмент ресурсов у всех получается по-разному, поэтому толк от D3D12 на практике есть не всегда.
Также в D3D12 были внедрены и некоторые дополнительные функции, о которых мы многократно рассказывали в своих материалах, посвященных новым графическим процессорам: консервативная растеризация, тайловые ресурсы, Raster Order Views, переменная частота затенения и другие. Пусть они кажутся не такими значимыми, как внедрение различных типов шейдеров в предыдущих версиях Direct3D, но они дают возможность или улучшить некоторые эффекты или реализовать совершенно новые. Большинство этих возможностей внедрены скорее для повышения эффективности рендеринга в уже существующих алгоритмах, но есть и кое-что новое и очень полезное, особенно для графических процессоров компании AMD.
Речь идет об асинхронных вычислениях. Современные графические процессоры состоят из большого количества различных исполнительных блоков, которые умеют исполнять разные программы, далеко не только графические. В частности, можно вспомнить давно известное аппаратное ускорение физических эффектов на GPU при помощи PhysX и различные фильтры постобработки, в том числе сложные алгоритмы имитации глобального освещения и затенения. Все это выполняется на GPU, и графические и неграфические вычисления вполне могут исполняться параллельно во многих случаях. Именно одновременное исполнение нескольких разных очередей инструкций и называется асинхронными вычислениями.
В качестве примера таких задач, которые можно исполнять параллельно, можно привести обновление карт теней или какие-то сложные алгоритмы постфильтрации — и чем сложнее математические вычисления в них, тем лучше. В последнее время к списку возможных нагрузок для асинхронных вычислений добавилась и часть работы при трассировке лучей, что также помогает повысить эффективность использования имеющихся у GPU ресурсов.
Если D3D11 предусматривает одну очередь инструкций только для графики, то новая версия API позволяет создать несколько отдельных очередей графических команд и других типов вычислений. Команды, исполняемые в разных очередях, могут быть зависимыми, и исполнение инструкций в одной из них может быть остановлено до получения результата из соседней, но они все равно исполняются вместе. Именно такой подход позволяет повысить эффективность использования имеющихся исполнительных блоков, что особенно полезно для графических процессоров AMD архитектуры GCN, которые несколько труднее загрузить работой на 100% их возможностей. Асинхронное исполнение помогает приблизиться к этому.
С графическими процессорами Nvidia дело обстоит сложнее. Часть чипов архитектуры Kepler (старшие модели) хоть и умеют запускать параллельные потоки с вычислениями, но это требует ручной оптимизации в каждом конкретном случае, имеет множество ограничений и в целом работает не слишком эффективно. В Maxwell второго поколения поддержку асинхронных вычислений улучшили, но некоторые ограничения все равно остались — динамическое распределение групп мультипроцессоров SM сделано сложно и недостаточно эффективно. Так что в играх с поддержкой D3D12 на этих GPU вряд ли получится какое-то ускорение от асинхронных вычислений, а чаще всего эта возможность вообще заблокирована в драйвере и открывается под каждое конкретное приложение.
Но в архитектуре Pascal многое изменилось, эти GPU могут распределять ресурсы мультипроцессоров между очередями команд динамически, и хотя смена контекста приводит к большой потере времени, возможности асинхронных вычислений в этом случае все равно не такие гибкие и эффективные, как в случае архитектуры GCN от конкурента. Все это привело к тому, что новые возможности используются не всеми игровыми разработчиками, ведь доля Nvidia на рынке игровых видеокарт для ПК выше. Но из-за использования графических ядер архитектуры GCN в консолях и помощи разработчикам игр от AMD, такая поддержка появляется во все большем количестве игр. Кроме этого, в последних чипах семейства Turing от Nvidia были устранены все недостатки предыдущих GPU компании, связанные с асинхронными вычислениями и они справляются с ними не хуже конкурента.
Вроде бы все наконец-то хорошо, но увы — даже объявленная поддержка D3D12 еще не значит, что игрой используются все новые функции этого API, не говоря уже о разной степени оптимизации кода, которой теперь в большей мере занимаются именно разработчики игр. В частности, менеджмент ресурсов (геометрии, текстур, буферов и т. п.) в новой версии API делается разработчиками игр самостоятельно, из-за этого иногда возникает больше проблем, чем это было с D3D11. Кроме этого, требования к объему видеопамяти у D3D12-версий чаще всего выше, также увеличена возможность появления ошибок и артефактов изображения. В качестве примера можно взять игру The Division 2, которая в D3D12-режиме при малейшей нехватке видеопамяти сразу же начинает сыпать артефактами, хотя эти же видеокарты с таким же объемом памяти прекрасно работают в D3D11-режиме.
Так, версия GeForce GTX 1060 с 3 ГБ видеопамяти в Full HD-разрешении при высоких настройках качества и использовании D3D11 показывает более чем 60 FPS, но переключение на DX12 приносит падение производительности вдвое — почти до 30 FPS. Именно менеджмент ресурсов, за который теперь отвечают разработчики игр, и привел к тому, что в D3D12 ей не хватает 3 ГБ видеопамяти. Разница между D3D11 и D3D12 именно в том, что в первом случае менеджментом ресурсов занимается API и видеодрайвер, а во втором — исключительно игровой код, написанный программистами конкретного проекта.
Эти недостатки не умаляют прелестей новой версии API, которая способна одним повышением эффективности рендеринга дать возможность увеличить количество и геометрическую сложность объектов в сцене, повысить качество эффектов и принести совершенно новые (чего стоит одна только трассировка лучей). Но делать исключительно D3D12-движок пока что никто не решается, так как устаревших видеокарт у пользователей еще довольно много, и чаще всего игры дают возможность выбора между D3D11 и D3D12. И зачастую они не будут выглядеть лучше в случае выбора более свежей версии API, а просто повысится производительность рендеринга, в лучшем случае. Сегодня мы попробуем разобраться, насколько полезно применение Direct3D 12 в современных играх.
Тестовый стенд и условия тестирования
Для того, чтобы сравнение видеокарт AMD и Nvidia было максимально корректным, мы взяли по одной видеокарте среднего уровня из предыдущего поколения: AMD Radeon RX 580 (8 ГБ) и Nvidia GeForce GTX 1060 (6 ГБ). А для того, чтобы проверить, не улучшился ли прирост от новой для D3D12 функциональности в графической архитектуре Turing, мы дополнительно протестировали еще и топовую Nvidia GeForce GTX 2080 Ti. Для всех видеокарт использовались последние версии драйверов, вышедшие на момент проведения тестов.
Так как прирост от использования новой версии API по опыту наших игровых тестов получается большим в режиме, когда скорость рендеринга ограничена CPU, то мы протестировали видеокарты сразу в двух режимах: при разрешении 1920×1080 и средних настройках качества (условно — ограниченный производительностью процессора режим) и при разрешении 2560×1440 и максимальных настройках качества (условно — режим, ограниченный производительностью видеокарты). И пусть GeForce GTX 2080 Ti даже во втором режиме частенько упирается в CPU, для основной пары сравниваемых видеокарт среднего ценового диапазона эти названия соответствуют условиям.
Тестирование производительности
Мы протестировали дюжину игр, в которых есть возможность переключения между рендерерами, использующими Direct3D 11 и Direct3D 12. Vulkan в этот раз не рассматривали, так как это все-таки иной API и напрямую сравнивать их было бы не совсем корректно. Сегодня же наша основная цель состоит в том, чтобы понять, какие преимущества (или наоборот) на практике дает использование более новой версии графического API от Microsoft для разных графических процессоров.
В список игровых проектов вошли только те игры, в которых есть встроенные бенчмарки — тестировать производительность в данном случае нужно точно, ведь при небольшой разнице в производительности, точность измерения и повторяемость нужно обеспечить максимально возможные. И еще — в этот раз мы приводим только средние показатели частоты кадров, а исследование минимальных показателей, да и вообще времени рендеринга кадров и их стабильности — дело отдельного материала. Там тоже будет много интересного.
Ashes of the Singularity: Escalation
Эта игра была одним из примеров хорошей оптимизации для D3D12 во время своего выхода, и с самого начала она отлично работала на видеокартах Radeon, а вот на GeForce дела были похуже. Но с того времени многое изменилось, теперь и графические процессоры Nvidia отлично с ней справляются. Видимо, из-за какой-то программной ошибки, Radeon RX 580 в наших условиях не получил большого прироста от перехода к D3D12, мы перепроверяли результат не один раз.
Зато обе видеокарты GeForce серьезно ускоряются именно в D3D12-версии игры — на 23% и 33% для старшей и младшей моделей. Но хорошо видно, что использование D3D12 для разгрузки CPU — не панацея, обе видеокарты остались ограничены мощностью центрального процессора. D3D11-видеодрайвер Nvidia оптимизирован довольно неплохо, но и конкурент им не сильно уступает в случае этой игры.
В более тяжелых для графических процессоров условиях, разница между версиями графического API ожидаемо снизилась, особенно для младшей пары видеокарт, но прирост в 10%-12% все же есть для среднебюджетных GPU обоих производителей. Старшая же GeForce RTX 2080 Ti даже в таких условиях частично ограничена мощностью CPU и получает от D3D12-рендерера заметное преимущество. Получается, что D3D12 полезнее именно для систем с мощными GPU.
Civilization VI
Похоже, что игра не слишком хорошо оптимизирована в ее D3D12-части, но еще хуже работает Radeon RX 580 в D3D11-режиме. Вероятно, в компании AMD решили, что все будут использовать D3D12 в случае Civilization VI (на диаграммах в названии игры опечатка) и просто незачем заморачиваться оптимизацией для младшей версии API. Наверное, смысл в этом есть, но уж очень велика разница в частоте кадров — почти двукратная.
Обе видеокарты GeForce в D3D11-режиме уперлись в производительность CPU, но старшая все же показала видимое ускорение порядка 14% при переходе к более свежей версии D3D, а вот младшая GTX 1060 в обоих режимах показывает очень близкий результат — судя по всему, D3D11-драйвер Nvidia отлично оптимизирован для этой игры.
В гораздо более тяжелых условиях с применением мультисэмплинга, Radeon RX 580 все еще получает некоторый прирост от новой версии API, но он уже значительно меньше. А вот что касается прямого конкурента этой модели — GeForce GTX 1060, то она в режиме D3D12 сдает позиции, так что на ней включать D3D12-рендерер не имеет смысла. Скорее всего, это связано с большим потреблением видеопамяти в D3D12-режиме, ведь объем VRAM у этой модели — 6 ГБ против 8 ГБ у Radeon.
Заметно более мощная и дорогая модель GeForce GTX 2080 Ti получает прирост производительности при переходе от D3D11 к D3D12, аналогичный тому, что было у (условного) конкурента от AMD, а видеопамяти у нее еще больше, так что повышенные требования к ее объему не сказываются негативно на скорости рендеринга в игре Civilization VI. Подтверждаем вывод, что больше всего смысла в D3D12 именно в случае самого мощного GPU.
Deus Ex: Mankind Divided
Еще одна игра, к созданию и оптимизации которой приложила руку компания AMD, поэтому она отлично работает на Radeon RX 580 и не очень хорошо — на обеих GeForce. Решение AMD стало единственным, которое обеспечивает прирост в режиме D3D12, хоть и довольно небольшой. Производительность рендеринга почти полностью зависит от GPU, поэтому и прирост низкий. Обе видеокарты Nvidia не просто не получают его, но и серьезно уступают себе же при использовании нового API — для GeForce RTX 2080 Ti падение скорости составило аж 24%, младшая же модель показала близкие результаты в обоих режимах.
В более сложном для GPU режиме ультра-настроек баланс загрузки сместился в сторону GPU, и разница между D3D11 и D3D12 уменьшилась, хотя знак остался тем же: Radeon RX 580 быстрее на пару-тройку процентов, GeForce GTX 1060 медленнее на 6%, а старшая видеокарта Nvidia семейства Turing и вовсе уступает себе же в D3D11-варианте уже 12%. Яркий пример игры, в которой польза от D3D12 есть только для видеокарт AMD. Это и неудивительно, так как разработчики игры с ними очень плотно сотрудничали.
Hitman 1
Что касается очередного проекта — Hitman 1, то эта игра в режиме ограничения производительности центральным процессором работает на всех представленных видеокартах абсолютно одинаково, обеспечивая 110-111 FPS в D3D11-режиме и 118-121 FPS в D3D12. Прирост от нового API есть на всех видеокартах и он составляет порядка 7%-9%, но похоже, что более интересным будет сравнение в более тяжелом для GPU режиме.
Похоже, что толк от более новой версии D3D в случае этой игры есть только при ограничении скорости рендеринга мощностью CPU, как это получилось и в этом случае для GeForce RTX 2080 Ti, которая ускорилась аж на 18% при включении D3D12-рендерера. А вот две младшие видеокарты от AMD и Nvidia показали практически идентичный результат в обоих режимах. Вывод все тот же — чем мощнее GPU, тем больше прирост от D3D12, так как скорость чаще упирается в CPU.
Hitman 2
Следующая игра серии сильнее нагружает графические процессоры, поэтому скорость рендеринга в ней не так сильно упирается в возможности CPU. Хотя некоторое ограничение есть, в D3D11-режиме все видеокарты близки. А вот при использовании D3D12 выделяется старшая видеокарта Nvidia, она одна получила прирост от более новой версии Direct3D, хоть и небольшой.
Удивительна разница между D3D11 и D3D12 для Radeon RX 580 и GeForce GTX 1060 — хотя она отрицательная для пары представленных в сравнении GPU среднего уровня, но больше всего от включения нового API пострадал почему-то Radeon, хотя куда чаще бывает наоборот. Посмотрим, что будет при увеличении нагрузки на графику.
В общем и целом, более тяжелые условия для GPU не принесли ничего нового, диаграмма схожа с предыдущей, за исключением того, что топовый Turing сильно вырвался вперед по абсолютным показателям. Парочка среднебюджетных Radeon RX 580 и GeForce GTX 1060 очень близка друг к другу в обоих режимах, решение AMD совсем чуть-чуть впереди, и для обоих нет смысла в D3D12, так как этот режим дает лишь падение скорости. А вот старшая видеокарта семейства GeForce RTX все еще получает прирост, упираясь в CPU, пусть уже и несколько меньше.
F1 2018
Игры от компании Codemasters под официальной лицензией Формулы 1 выходят постоянно, но они мало меняются год от года с графической точки зрения. Впрочем, F1 2018 стала первой, в которой появилась бета-поддержка Direct3D12, и мы этим воспользовались. Похоже, что D3D11-драйвер у AMD не очень хорошо оптимизирован и для этой игры, потому что прирост от включения D3D12 получился более чем на 50%. А вот для Nvidia разница составила всего лишь 9% и 2% для GTX 1060 и RTX 2080 Ti, соответственно, но тоже в пользу нового API.
Зато в более тяжелом режиме ситуация совершенно иная. Младший представитель Nvidia не получает от включения D3D12 никаких преимуществ, а Radeon RX 580 довольствуется 10% прироста. Примерно такая же разница для двух режимов с разными графическими API и для GeForce RTX 2080 Ti, так что в случае тяжелого для GPU режима все похоже на ничью.
Rise of the Tomb Raider
Хорошо видно, что более старая игра приключений Лары Крофт не слишком хорошо оптимизирована для Direct3D12, разница между двумя версиями API составляет лишь до 9%, но если GTX 1060 почти не получает преимущества, то две другие видеокарты показали видимый прирост частоты кадров, хоть и не слишком большой. Посмотрим, что получится в тяжелом для видеочипов режиме:
Как ни странно, но ситуация осталась почти без изменений, только относительные цифры прироста снизились, и теперь он составляет от 2% до 5% — всегда в пользу более новой версии D3D. Старшая GeForce RTX 2080 Ti заметно быстрее других видеокарт, но и для нее разница между D3D11 и D3D12 составляет лишь 5%. Главный вывод — можно смело включать D3D12-режим для видеокарт и AMD и Nvidia, и чем мощнее GPU — тем больше прирост в частоте кадров.
Shadow of the Tomb Raider
Последняя игра серии Tomb Raider получила более продвинутый D3D12-рендерер, и он явно работает лучше на видеокартах Nvidia, что тоже неудивительно, ведь именно они помогали разработчикам игры при оптимизации кода. В то время как Radeon RX 580 в D3D12-режиме уступил самому себе 5% при сравнении с D3D11-версией, GeForce GTX 1060 показала прирост скорости в 13%, а топовая карта семейства Turing вообще была почти на треть быстрее при использовании нового API.
Нагрузка на GPU увеличилась, но не настолько, чтобы скорость упиралась в него в случае GeForce RTX 2080 Ti, поэтому для этой модели выводы остались прежними — в D3D12-режиме скорость заметно выше, а нагрузка на CPU меньше. А вот парочка среднебюджетных решений, ставших весьма популярными за несколько лет, показывает очень близкие результаты в обоих режимах — обе они обеспечивают 37-39 FPS, в зависимости от условий.
The Division 1
Первая игра сериала The Division получила D3D12-рендерер не сразу по выходу, а несколько позднее. Похоже, что он не слишком хорошо подходит для графических решений Nvidia, которые не получают прироста от его использования, а старшая GeForce RTX 2080 Ti даже снижает производительность на несколько процентов. В то же время, единственный Radeon в нашем материале дает почти 10% прирост от применения нового API.
Примерно то же самое получается и при усложнении задачи для графических процессоров — повышение разрешения и качества рендеринга привело к снижению прироста и падения скорости, но их знак остался тем же: на GeForce GTX 1060 выбор API не влияет ни на что, старшая GeForce немного теряет в D3D12-режиме, а модель Radeon RX 580 оказалась быстрее при использовании новой версии API, но уже лишь на 6%.
The Division 2
Вторая часть игры явно смотрится лучше уже в D3D12-варианте, причем сразу на всех участвующих в нашем сравнении графических процессорах. Решения среднего уровня от AMD и Nvidia получают прирост от нового API порядка 10%-12%, хотя при этом Radeon RX 580 оказывается заметно производительнее своего прямого конкурента, а вот GeForce RTX 2080 Ti довольствуется вдвое меньшим приростом в частоте кадров от D3D12.
Ситуация переворачивается с ног на голову при увеличении нагрузки на GPU. Теперь среднебюджетные Radeon RX 580 и GeForce GTX 1060 показывают прирост скорости рендеринга лишь на 8% и 3%, соответственно, а вот старшая видеокарта Nvidia в более сложных для GPU условиях показала прирост FPS аж на 18%. Так что главные выводы все те же. Во-первых, в случае игры The Division 2 можно использовать D3D12-режим на видеокартах обеих компаний: AMD и Nvidia. А во-вторых, толку от нового API тем больше, чем мощнее GPU относительно CPU.
Total War: Warhammer II
Увы, но в случае игры Total War: Warhammer II, режим использования Direct3D12 остается в опытном варианте, и он абсолютно на всех видеокартах серьезно проигрывает D3D11-рендереру. Если для среднеценовых видеокарт Radeon RX 580 и GeForce GTX 1060 падение производительности составило 14%-17%, то для топовой видеокарты семейства GeForce RTX это уже минус треть скорости от D3D11-режима, что просто неприемлемо. Налицо плохая оптимизация разработчиками. Неудивительно, что из более новой Total War: Three Kingdoms такую кривую поддержку выкинули.
Почти то же самое отмечается и в более сложном графически режиме с повышенным разрешением рендеринга и максимальным качеством графики. Абсолютно все GPU при использовании более нового графического API уступают себе же в D3D11-варианте. Видеокарты средней мощности довольствуются падением частоты кадров на 10%-18%, а старшая GeForce — сразу на 27%. Вердикт: не включать D3D12 в этой игре ни в коем случае!
Metro Exodus
Игра Metro Exodus вышла не так давно, и кроме поддержки трассировки лучей DXR, имеет и D3D12-рендерер. Не очень понятно, кто виноват в таком качестве оптимизации, но на Radeon RX 580 мы отмечаем небольшой прирост в скорости рендеринга при переключении API на более новый (5%), а вот на GeForce GTX 1060 получается −4%. И если для D3D11 они обе показали 56 FPS, то в D3D12-режиме разница явно в пользу Radeon. А GeForce RTX 2080 Ti так и вовсе поразила падением скорости более чем на 20%. А ведь игра разрабатывалась с поддержкой компании Nvidia.
Даже на средних настройках в Full HD-разрешении производительность в игре упирается в GPU, ну а при усложнении задачи графический процессор и вовсе становится единственным ограничителем скорости рендеринга. Прирост от включения D3D12 в случае Radeon RX 580 немного увеличился, а вот обе GeForce все так же не получают никаких преимуществ от более современного рендерера, но хотя бы падение скорости стало меньше. В общем, польза от нового API в этой игре снова есть только для Radeon, да и то небольшая.
Выводы
Что хочется сразу отметить — все игры очень разные и сделать однозначные выводы по ним не получится. Средние показатели, полученные при сравнении двух разных версий API, дают не очень много информации, хотя кое-что можно понять и по ним. Уж очень по-разному сделаны D3D11 и D3D12-версии движков в разных играх. Соответственно, и ведут они себя совершенно по-разному на различных GPU, и две-три игры с большим падением или приростом FPS могут очень сильно повлиять на средний счет.
Архитектуры графических процессоров AMD и Nvidia сильно отличаются, качество кода для D3D12 тоже разное. Достаточно сравнить The Division 2, в котором все GPU получают преимущество от новой версии API, и Total War: Warhammer II, в которой на всех видеокартах отмечено сильное падение производительности. Поэтому лучше рассматривать сочетания конкретной игры и отдельных GPU. Но все же приведем средние показатели чисто справочно:
1920×1080 medium | 2560×1440 maximum | |
---|---|---|
Radeon RX 580 | 11% | 3% |
GeForce GTX 1060 | 4% | −3% |
GeForce RTX 2080 Ti | 2% | 8% |
Как видите, по средним цифрам можно увидеть лишь то, что Radeon RX 580 в среднем лучше справляется в D3D12 в режиме средней нагрузки на GPU и большой на CPU. Это может быть вызвано в том числе и тем, что при ограничении производительности рендеринга универсальным процессором, D3D11-драйвер AMD не слишком хорошо оптимизирован для многопоточной работы. У Nvidia такая оптимизация лучше, и в режиме невысокой нагрузки на GPU видеокарты GeForce и в D3D11 выглядят неплохо.
Еще один интересный вывод по средним цифрам — в более тяжелом режиме явно виден сильный прирост скорости у GeForce RTX 2080 Ti. Так получилось из-за того, что даже в повышенном разрешении при максимальных настройках общая скорость рендеринга частенько упиралась в CPU, а в этом случае применение D3D12 дает преимущество. Получается, что больше всего смысла в использовании новой версии D3D будет именно для более мощных GPU.
Мы намеренно не взяли в сравнение архитектуру Kepler — новую версию API эти GPU поддерживают лишь номинально, в некоторых играх D3D12-рендереры вообще не работают на таких GPU, а где работают, то не только не отмечается прироста производительности, а она даже значительно ухудшается, чаще всего. Да и архитектура Maxwell не очень хороша в D3D12-играх, чаще всего и на этих GPU прироста мы не видим. Кроме этого, видеокарты с малым количеством видеопамяти всегда страдают в случае D3D12 больше, так как программисты хуже оптимизируют код, чем это делает предыдущая версия графического API. Мы увидели это на примере игры Civilization IV, в которой в том числе использовался мультисэмплинг, предъявляющий повышенные требования к объему VRAM.
Что можно выделить еще — в случае режима с высокой загрузкой GPU, у видеокарт AMD все неплохо, от новой версии API они получают прирост частоты кадров во многих случаях, хоть и небольшой. За исключением высоких разрешений при малом объеме видеопамяти и некоторых игр, в которых D3D12-движок сделан явно не очень хорошо. Для Pascal в лице GeForce GTX 1060 новая версия API помогает несколько меньше, а иногда и вовсе дает отрицательный прирост FPS.
При упоре производительности в возможности CPU, новая версия Direct3D дает куда больший прирост в большем количестве случаев, и особенно это касается видеокарт AMD, D3D11-драйвер у которых несколько хуже оптимизирован. В своих обзорах мы не раз отмечали, что в таких случаях Radeon частенько проигрывает аналогичным по скорости картам GeForce. Но теперь, когда Direct3D12 используется все чаще, ситуация начинает улучшаться. И игр с поддержкой нового API будет все больше.
Повторим главный вывод нашего небольшого исследования — все игры и движки по-разному оптимизированы для новой версии графического API DirectX, и почти невозможно дать универсальный совет, стоит ли включать D3D12-рендерер или нет. Слишком многое зависит от разработчиков игр, и в случае новой версии D3D их влияние лишь усилилось. На многое также влияет и поддержка со стороны производителей GPU, которые помогают оптимизировать код именно под свои решения. Но DirectX 12 API точно дает важные преимущества и включать его в большинстве игр можно уже без особых опасений.