Поделиться через


Direct3D 11 на 12

D3D11On12 — это механизм, с помощью которого разработчики могут использовать интерфейсы и объекты D3D11 для управления API D3D12. D3D11on12 позволяет компонентам, написанным с помощью D3D11 (например, текст D2D и пользовательский интерфейс), работать вместе с компонентами, предназначенными для API D3D12. D3D11on12 также включает добавочный перенос приложения из D3D11 в D3D12, позволяя части приложения продолжать ориентироваться на D3D11 для простоты, а другие — D3D12 для производительности, при этом всегда выполняя полную и правильную отрисовку. D3D11On12 упрощает использование методов взаимодействия для совместного использования ресурсов и синхронизации работы между двумя API.

Инициализация D3D11On12

Чтобы начать использовать D3D11On12, сначала создайте устройство D3D12 и очередь команд. Эти объекты предоставляются в качестве входных данных для метода инициализации D3D11On12CreateDevice. Этот метод можно рассматривать как создание устройства D3D11 с мнимым типом драйвера D3D_DRIVER_TYPE_11ON12, где драйвер D3D11 отвечает за создание объектов и отправку списков команд в API D3D12.

После создания устройства D3D11 и непосредственного контекста вы можете QueryInterface отключить его для интерфейса ID3D11On12Device . Это основной интерфейс, используемый для взаимодействия между D3D11 и D3D12. Чтобы контекст устройства D3D11 и списки команд D3D12 работали с теми же ресурсами, необходимо создать "упакованные ресурсы" с помощью API CreateWrappedResource . Этот метод "повышает" ресурс D3D12, чтобы быть понятным в D3D11. Заключенный в оболочку ресурс начинается в состоянии "приобретенный", свойство, которым управляют методы AcquireWrappedResources и ReleaseWrappedResources .

Example Usage (Пример использования)

Обычно D3D11On12 использует D2D для отрисовки текста или изображений поверх обратного буфера D3D12. Пример кода см. в примере D3D11On12. Ниже приведены приблизительные сведения о действиях, которые необходимо выполнить для этого.

  • Создайте устройство D3D12 (D3D12CreateDevice) и цепочку буферов D3D12 (CreateSwapChain с ID3D12CommandQueue в качестве входных данных).
  • Создайте устройство D3D11On12 с помощью устройства D3D12 и той же очереди команд, что и входные данные.
  • Получите обратные буферы цепочки буферов и создайте для каждого из них упакованные ресурсы D3D11. Используемое входное состояние должно быть последним способом использования D3D12 (например, RENDER_TARGET), а выходное состояние должно быть таким, как D3D12 будет использовать его после завершения D3D11 (например, PRESENT).
  • Инициализируйте D2D и предоставьте D2D-файлу упакованные ресурсы D3D11 для подготовки к отрисовке.

Затем для каждого кадра выполните следующие действия.

  • Отрисуйте в текущем буфере обратной цепочки буферов с помощью списка команд D3D12 и выполните его.
  • Получите ресурс в оболочке текущего обратного буфера (AcquireWrappedResources).
  • Выдача команд отрисовки D2D.
  • Освобождение упакованного ресурса (ReleaseWrappedResources).
  • Немедленное освобождение контекста D3D11.
  • Present (IDXGISwapChain1::P resent1).

История

D3D11On12 работает систематически. Каждый вызов API D3D11 проходит стандартную проверку среды выполнения и направляется к драйверу. На уровне драйверов специальный драйвер 11on12 записывает состояние и выдает операции отрисовки в списках команд D3D12. Эти списки команд отправляются по мере необходимости (например, для запроса GetData или ресурса Map может потребоваться очистка команд) или в соответствии с запросом Flush. Создание объекта D3D11 обычно приводит к созданию соответствующего объекта D3D12. Некоторые фиксированные операции отрисовки функций в D3D11, такие как GenerateMips или DrawAuto , не поддерживаются в D3D12, поэтому D3D11On12 эмулирует их с помощью шейдеров и дополнительных ресурсов.

Для взаимодействия важно понимать, как D3D11On12 взаимодействует с объектами D3D12, созданными и предоставленными приложением. Чтобы убедиться, что работа выполняется в правильном порядке, перед отправкой дополнительных работ D3D12 в очередь необходимо очистить непосредственный контекст D3D11. Кроме того, важно убедиться, что очередь, отдаваемая D3D11On12, должна быть постоянно истощаемой. Это означает, что все ожидания в очереди в конечном итоге должны быть удовлетворены, даже если поток отрисовки D3D11 блокируется на неопределенный срок. Будьте осторожны, чтобы не зависеть от того, когда D3D11On12 вставляет записи или ожидания, так как это может измениться в будущих выпусках. Кроме того, D3D11On12 самостоятельно отслеживает состояния ресурсов и управляет ими. Единственный способ обеспечить когерентность переходов состояния — использовать API получения и выпуска для управления отслеживанием состояния в соответствии с потребностями приложения.

Очистка

Чтобы освободить ресурс d3D11On12 в оболочке, в этом порядке необходимо выполнить две вещи:

  • Все ссылки на ресурс, включая все представления ресурса, должны быть освобождены.
  • Должна выполняться отложенная обработка уничтожения. Самый простой способ убедиться в этом — вызвать API непосредственного контекста Flush .

После завершения обоих этих шагов все ссылки, сделанные упакованным ресурсом, должны быть освобождены, а ресурс D3D12 становится исключительно принадлежащим компоненту D3D12. Имейте в виду, что D3D12 по-прежнему требуется дождаться завершения работы GPU перед полным освобождением ресурса, поэтому обязательно держите ссылку на ресурс, прежде чем выполнять два описанных выше шага, если только вы не подтвердили, что GPU больше не использует ресурс.

Все остальные ресурсы или объекты, созданные D3D11On12, будут очищены в соответствующее время, когда GPU завершит их использование с помощью механизма отложенного уничтожения D3D11. Однако при попытке освободить само устройство D3D11On12 во время выполнения gpu, уничтожение может блокироваться до завершения работы GPU.

Ограничения

Уровень D3D11On12 реализует очень большое подмножество API D3D11, но есть некоторые известные пробелы (в дополнение к ошибкам в реализации, которые могут привести к неправильной отрисовке).

По состоянию на Windows 10, версия 1809 (10,0; Сборка 17763), если D3D11On12 работает на драйвере, поддерживающем шейдерную модель 6.0 или более поздней версии, он может запускать шейдеры, использующие интерфейсы. В более ранних версиях Windows функция интерфейсов шейдеров не реализована в D3D11On12, и попытка использовать эту функцию приведет к ошибкам и сообщениям отладки.

Начиная с Windows 10, версия 1803 (10.0; Сборка 17134), цепочки буферов поддерживаются на устройствах D3D11On12. В более ранних версиях Windows это не так.

D3D11On12 не оптимизирован для производительности. По сравнению со стандартным драйвером D3D11, скорее всего, будут средние затраты на ЦП, минимальные затраты на GPU, а также значительные затраты на память. Поэтому не рекомендуется использовать D3D11On12 для сложных трехмерных сцен, а вместо этого рекомендуется использовать для простых сцен или двухd-отрисовки.

Программные интерфейсы

Api, составляющие слой 11on12, описаны в справочнике по 11on12.

Пошаговые инструкции по D2D с использованием D3D11on12

Основные сведения о Direct3D 12

Работа с Direct3D 11, Direct3D 10 и Direct2D