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


Расширенные барьеры D3D12

Интерфейс DDI для расширенных барьеров доступен в Windows 11 версии 22H2 WDK (WDDM 3.0). Чтобы использовать расширенные барьеры на версии 22H2 (или более ранних выпусках ОС), необходимо установить пакет SDK 1.706.4-preview Agility.

Расширенные барьеры D3D12 предоставляют разработчикам независимый контроль над синхронизацией работы GPU, переходами макета текстур и очисткой кэша (доступ к памяти ресурсов). Эта функция предлагает набор API Direct3D и DDIs, которые обеспечивают разработчикам независимый контроль над синхронизацией рабочих процессоров GPU, переходами макета текстур и очисткой кэша (доступ к памяти ресурсов).

Расширенные барьеры заменяют устаревшие барьеры ресурсов более экспрессивными типами барьеров. Они имеют следующие функции:

  • Меньше задержки синхронизации.
  • Снижение избыточного сброса кэша.
  • Нет таинственных правил продвижения и распада.
  • Быстрый, гибкий псевдоним ресурсов (разнообразные топологии псевдонимов).
  • Отмена при переходе барьера.
  • Поддержка параллельного чтения и записи, включая копию одного ресурса (самостоятельную копию).
  • Поддержка асинхронной отмены, копирования, разрешения и очистки команд.

Расширенные барьеры не являются более простыми, чем устаревшие барьеры ресурсов, но они менее неоднозначны и поэтому проще для разработчиков.

Создание отчетов о расширенной поддержке барьеров

Функция расширенных барьеров в настоящее время не является требованием к оборудованию или драйверу. Драйвер указывает поддержку, задав для элемента EnhancedBarriersSupported D3D12DDI_D3D12_OPTIONS_DATA_0089 значение TRUE.

  • D3D12DDI_FEATURE_VERSION_VIDEO_0088_0 — это номер версии, определяющий предварительную реализацию расширенных вех барьеров D3D12, представленных в Windows 11.

Расширенные функции обратного вызова d3D12

Драйверы, указывающие на поддержку расширенных барьеров, реализуют следующие функции обратного вызова:

Технические подробности

Драйверы обычно обрабатывают устаревшие барьеры ресурсов с помощью трех отдельных операций:

  1. Синхронизация работы GPU.
  2. Выполните все необходимые операции очистки кэша.
  3. Выполните все необходимые изменения макета.

Расширенные барьеры дают разработчикам возможность управлять каждой из этих операций отдельно.

Типы расширенных барьеров

Существует три типа расширенных барьеров:

Диапазонные барьеры заменяют устаревшие барьеры ресурсов. Диапазонные барьеры предоставляются таким образом, чтобы устаревшие барьеры ресурсов могли быть полностью реализованы без заметной потери производительности.

  • Все типы барьеров управляют синхронизацией работы GPU и типами доступа для чтения или записи до и после барьера.

  • Барьеры текстур также управляют макетом подресурсов текстур. Выбор подресурсов можно выразить в виде диапазона срезов mip, массива и плоскости, в дополнение к знакомому варианту один или все, используемому устаревшими барьерами ресурсов.

  • Буферные барьеры и глобальные барьеры управляют только синхронизацией и доступом к ресурсам и не влияют на макет ресурса (буферы не имеют макета). Глобальные барьеры влияют на всю кэшированную память, чтобы они могли быть дорогостоящими и должны использоваться только в том случае, если более ограниченный барьер недостаточно.

Барьеры текстуры

  • Управление очисткой кэша, макетом памяти и синхронизацией для подресурсов текстур.
  • Необходимо использовать только с ресурсами текстуры.
  • Разрешить выбор одного подресурса, всех подресурсов или последовательного диапазона подресурсов (то есть диапазона MIP и диапазона массивов).
  • Должен предоставлять допустимый указатель ресурсов, отличный от NULL.

Буферные барьеры

  • Управление очисткой кэша и синхронизацией для буферных ресурсов.
  • Необходимо использовать только с буферными ресурсами.
  • В отличие от текстур, буферы имеют только один подресурс и не имеют макета, который можно перенести.
  • Должен предоставлять допустимый указатель ресурсов, отличный от NULL.

Глобальные барьеры

  • Управление очисткой кэша и синхронизацией для всех указанных типов доступа к ресурсам в одной очереди команд.
  • Не влияет на макет текстуры.
  • Необходимы для обеспечения функциональных возможностей, аналогичных устаревшим барьерам UAV NULL и барьерам псевдонима NULL/NULL.

Так как глобальные барьеры не переходят макет текстуры, глобальные барьеры нельзя использовать в переходах, которые в противном случае требуют изменения макета. Например, глобальный барьер нельзя использовать для перехода текстуры не одновременного доступа с D3D12DDI_BARRIER_ACCESS_RENDER_TARGET на D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE, так как это также потребует изменения с D3D12DDI_BARRIER_LAYOUT_RENDER_TARGET на D3D12DDI_BARRIER_LAYOUT_SHADER_RESOURCE.

Синхронизация

Графические процессоры предназначены для параллельного выполнения максимальной работы. Перед доступом к зависимым данным необходимо синхронизировать любую работу GPU, зависящую от предыдущей работы GPU.

Расширенный интерфейс барьера использует явные значения SyncBefore и SyncAfter в качестве маскировок логических битовых полей. Барьер должен ожидать завершения всех предыдущих областей SyncBefore перед выполнением барьера. Аналогичным образом барьер должен блокировать все последующие области SyncAfter , пока барьер не завершится. D3D12DDI_BARRIER_SYNC указывает область синхронизации работы GPU относительно барьера.

Дополнительные сведения см. в спецификации расширенных барьеров.

Переходы макета

Подресурс текстуры может использовать различные макеты для различных методов доступа. Например, текстуры часто сжимаются при использовании в качестве целевого объекта отрисовки или набора элементов глубины и часто распаковываются для команд чтения или копирования шейдера. Барьеры текстур используют значения LayoutBefore и LayoutAfter D3D12DDI_BARRIER_LAYOUT для описания переходов макета.

Переходы макета необходимы только для текстур, поэтому они выражаются только в структуре данных D3D12DDI_TEXTURE_BARRIER .

Как LayoutBefore, так и LayoutAfter должны быть совместимы с типом очереди, выполняющей барьер. Например, очередь вычислений не может перенести подресурс в D3D12DDI_BARRIER_LAYOUT_RENDER_TARGET.

Чтобы обеспечить четко определенное упорядочение барьеров, макет подресурса после завершения последовательности барьеров является окончательным LayoutAfter в последовательности.

Переходы доступа

Так как многие операции записи GPU кэшируются, любой барьер от доступа записи к другому доступу на запись или доступ только для чтения может потребовать очистки кэша. Расширенные API-интерфейсы барьеров используют переходы доступа, чтобы указать, что память подресурса должна быть видна для определенного нового типа доступа. Как и переходы макета, некоторые переходы доступа могут не потребоваться, если известно, что память связанного подресурса уже доступна для требуемого использования.

Переходы доступа выражаются следующим образом:

  • Для текстур в составе структуры D3D12DDI_TEXTURE_BARRIER.
  • Для буферов в составе структуры D3D12DDI_BUFFER_BARRIER.

Переходы доступа не выполняют синхронизацию. Ожидается, что синхронизация между зависимыми доступами обрабатывается с помощью соответствующих значений SyncBefore и SyncAfter в барьере.

AccessBefore, видимый для указанного accessAfter, не гарантирует, что память ресурсов также отображается для другого типа доступа. Например:

MyTexBarrier.AccessBefore=D3D12DDI_BARRIER_ACCESS_UNORDERED_ACCESS;
MyTexBarrier.AccessAfter=D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE;

Этот переход доступа означает, что последующий доступ на чтение шейдера зависит от предыдущей неупорядоченной записи. Однако если оборудование может считывать ресурсы шейдера непосредственно из кэша UAV, драйвер не может фактически очистить кэш UAV.

D3D12DDI_BARRIER_ACCESS_COMMON

D3D12DDI_BARRIER_ACCESS_COMMON — это специальный тип доступа, указывающий доступ, совместимый с макетом. Переход на D3D12DDI_BARRIER_ACCESS_COMMON означает, что данные подресурса должны быть доступны для любого доступа, совместимого с макетом после барьера. Так как буферы не имеют макета, D3D12DDI_BARRIER_ACCESS_COMMON просто означает доступ, совместимый с буфером.

Указание D3D12DDI_BARRIER_ACCESS_COMMON в качестве AccessBefore в барьере подразумевает набор всех типов доступа к записи. Использование D3D12DDI_BARRIER_ACCESS_COMMON в качестве AccessBefore не рекомендуется, так как это может привести к дорогостоящим, непреднамеренным сбросам кэша. Вместо этого разработчикам рекомендуется использовать только самые узкие биты доступа к записи для правильного ограничения нагрузки на барьер. Предупреждение об уровне отладки выдается, если для AccessBefore задано значение D3D12DDI_BARRIER_ACCESS_COMMON.

Одновременный доступ в одной очереди

Расширенные барьеры позволяют одновременно выполнять операции чтения и записи в одном буфере или текстуре одновременного доступа в одной очереди команд.

Буферы и ресурсы одновременного доступа всегда поддерживают доступ на запись из одной очереди с одновременным, независимым, доступом на чтение из одной или нескольких других очередей. Эта поддержка обусловлена тем, что такие ресурсы всегда используют общий макет и не имеют рисков чтения и записи, так как операции чтения не должны зависеть от одновременных операций записи. (Устаревшие правила барьера ресурсов запрещают объединение битов состояния записи с любыми другими битами состояния. Таким образом, ресурсы не могут быть одновременно считываемыми и записанными в одну очередь с использованием устаревших барьеров ресурсов.)

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

Диапазоны подресурсов

Обычно разработчики хотят перейти к диапазону подресурсов. Примером является переход полной цепочки MIP для заданного массива текстур или одного уровня MIP для всех срезов массива. Расширенные барьеры позволяют разработчикам переходить логически смежные диапазоны подресурсов с помощью структуры D3D12DDI_BARRIER_SUBRESOURCE_RANGE. (Устаревшие барьеры перехода состояния ресурса предоставляют разработчикам возможность перехода всех состояний подресурса или одного состояния подресурса атомарно.)

Макеты вычислительных и прямых очередей

Следующие расширенные макеты барьеров гарантированно совпадают как для прямых, так и для вычислительных очередей:

  • D3D12DDI_BARRIER_LAYOUT_GENERIC_READ
  • D3D12DDI_BARRIER_LAYOUT_UNORDERED_ACCESS
  • D3D12DDI_BARRIER_LAYOUT_SHADER_RESOURCE
  • D3D12DDI_BARRIER_LAYOUT_COPY_SOURCE
  • D3D12DDI_BARRIER_LAYOUT_COPY_DEST

Подресурс в одном из этих макетов можно использовать в прямых очередях или вычислительных очередях без перехода макета.

На некотором оборудовании переходные барьеры макета в прямых очередях могут быть значительно быстрее, если оба предыдущих или последующих доступа также находятся в прямых очередях. Настоятельно рекомендуется получить доступ к ресурсам в прямых очередях, используя следующие макеты:

  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE
  • D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST

Варианты макета DIRECT_QUEUE несовместимы с очередями вычислений и не могут использоваться в барьерах списка команд вычислений. Однако они совместимы с операциями вычислений в прямых очередях.

Бесплатный барьерный доступ

Так как между границами ExecuteCommandLists не должно быть ожидающих команд или операций очистки кэша, буферы могут быть изначально доступны в области ExecuteCommandLists без барьера. Аналогичным образом подресурс текстуры также может быть изначально доступ к ней без барьера в следующих условиях:

  • Макет подресурс совместим с типом доступа.
  • Инициализируется все необходимые метаданные сжатия.

Подресурс текстуры в D3D12DDI_BARRIER_LAYOUT_COMMON макета (или общий макет для конкретной очереди, например D3D12DDI_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON), которые не имеют потенциально невыполненных операций чтения или записи, можно получить в потоке команд ExecuteCommandLists без барьера с помощью любого из следующих типов доступа:

  • D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE
  • D3D12DDI_BARRIER_ACCESS_COPY_SOURCE
  • D3D12DDI_BARRIER_ACCESS_COPY_DEST

Кроме того, буфер или текстура, использующий общий макет очереди, может использовать D3D12DDI_BARRIER_ACCESS_UNORDERED_ACCESS без барьера.

Буферы и текстуры одновременного доступа (текстуры, созданные с флагом D3D12DDI_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS), могут быть изначально доступны в потоке команд ExecuteCommandLists без барьера с помощью любого из следующих типов доступа:

  • D3D12DDI_BARRIER_ACCESS_VERTEX_BUFFER
  • D3D12DDI_BARRIER_ACCESS_CONSTANT_BUFFER
  • D3D12DDI_BARRIER_ACCESS_INDEX_BUFFER
  • D3D12DDI_BARRIER_ACCESS_RENDER_TARGET
  • D3D12DDI_BARRIER_ACCESS_UNORDERED_ACCESS
  • D3D12DDI_BARRIER_ACCESS_SHADER_RESOURCE
  • D3D12DDI_BARRIER_ACCESS_STREAM_OUTPUT
  • D3D12DDI_BARRIER_ACCESS_INDIRECT_ARGUMENT
  • D3D12DDI_BARRIER_ACCESS_COPY_DEST
  • D3D12DDI_BARRIER_ACCESS_COPY_SOURCE
  • D3D12DDI_BARRIER_ACCESS_RESOLVE_DEST
  • D3D12DDI_BARRIER_ACCESS_RESOLVE_SOURCE
  • D3D12DDI_BARRIER_ACCESS_PREDICATION

Последующие доступы также можно сделать без барьера без нескольких типов доступа на запись. Однако, за исключением D3D12DDI_BARRIER_ACCESS_RENDER_TARGET, необходимо использовать барьеры для последовательной записи в тот же ресурс.

Самостоятельное копирование ресурсов

Хотя и не относится исключительно к расширенным барьерам, возможность разрешать копии из одного региона подресурса в другой неинтерсекционный регион является весьма запрошенной функцией. Благодаря расширенным барьерам подресурс с общим макетом можно использовать как источник, так и назначение в одном вызове CopyBufferRegion или CopyTextureRegion. Копии между пересекающимися областями исходной и целевой памяти создают неопределенные результаты. Уровень отладки ДОЛЖЕН проверяться на наличие таких результатов. (Устаревшая конструкция барьера ресурсов не позволяет подресурсу находиться как в D3D12DDI_RESOURCE_STATE_COPY_SOURCE, так и в состоянии D3D12DDI_RESOURCE_STATE_COPY_DEST одновременно, и поэтому не может копироваться в себя.)

Инициализация метаданных ресурсов

Устаревшая структура барьера ресурсов требует очистки, копирования или отмены для инициализации недавно размещенных и активированных ресурсов текстуры с псевдонимом перед использованием в качестве целевого объекта визуализации или набора элементов глубины. Это требование связано с тем, что ресурсы целевого объекта подготовки и глубины отрисовки обычно используют метаданные сжатия, которые должны быть инициализированы для допустимых данных. То же самое относится к зарезервированным текстурам с недавно обновленным сопоставлением плиток.

Расширенные барьеры поддерживают возможность отмены в рамках барьера. Макет барьеров переходит с D3D12DDI_BARRIER_LAYOUT_UNDEFINED на любой потенциально сжатый макет (например, D3D12DDI_BARRIER_LAYOUT_RENDER_TARGET, D3D12DDI_BARRIER_LAYOUT_DEPTH_STENCIL, D3D12DDI_BARRIER_LAYOUT_UNORDERED_ACCESS) ДОЛЖЕН инициализировать метаданные сжатия при наличии D3D12DDI_TEXTURE_BARRIER_FLAG_DISCARD в элементе D3D12DDI_TEXTURE_BARRIER::Flags.

Помимо ресурсов целевого объекта и глубины и набора элементов, существуют аналогичные оптимизации сжатия текстурЫ UAV, которые не поддерживает устаревшая модель барьерного барьера.

Порядок барьеров

Барьеры помещаются в очередь в порядке пересылки (порядок вызовов API, барьер-группа-индекс, барьер-массив-индекс). Несколько барьеров в одном подресурсе должны функционировать так, как будто барьеры выполняются в порядке очереди.

В очереди барьеры с соответствующими областями SyncAfter , которые потенциально записываются в одну память, должны завершить все операции записи в очереди. Это требование позволяет избежать рас данных на барьерах, поддерживающих псевдоним ресурсов. Например, барьер, который деактивирует ресурс, должен сбрасывать все кэши перед другим барьером, который активирует другой ресурс в той же памяти, что и возможно очистка метаданных.