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


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.

Пример использования

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

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

Затем в каждом кадре сделайте следующее:

  • Отрисовка в текущий буфер цепочки буферов с помощью списка команд 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, созданными и предоставленными приложением. Чтобы убедиться, что работа выполняется в правильном порядке, немедленный контекст D3D11 должен быть удален перед отправкой дополнительных работ D3D12 в этой очереди. Кроме того, важно убедиться, что очередь, предоставленная D3D11On12, всегда должна быть стекаемой. Это означает, что все ожидания в очереди в конечном итоге должны быть удовлетворены, даже если блоки потока D3D11 отрисовывается на неопределенный срок. Не будьте осторожны, чтобы не принимать зависимость от того, когда D3D11On12 вставляет очистки или ожидания, так как это может измениться с последующими выпусками. Кроме того, D3D11On12 отслеживает и управляет состояниями ресурсов самостоятельно. Единственный способ обеспечить совместное использование интерфейсов API получения и выпуска для управления отслеживанием состояния в соответствии с потребностями приложения.

Очистка

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

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

После завершения обоих этих действий все ссылки, сделанные в оболочке, должны быть выпущены, и ресурс 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 для сложных трехмерных сцен, и вместо этого рекомендуется использовать простые сцены или 2D-отрисовку.

Пчела

API- интерфейсы, составляющие слой 11on12, описаны в 11on12 Reference.

D2D с помощью пошагового D3D11on12

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

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