Корневая подпись версии 1.1

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

Общие сведения

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

Приложения часто тривиально могут:

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

Кроме того, приложение может только учитывать, что данные не изменяются в течение более короткого времени. В частности, данные могут быть статическими для окна во времени во время выполнения списка команд, что привязка корневого параметра (таблица дескриптора или корневой дескриптор) в настоящее время указывает на данные. Иными словами, приложению может потребоваться выполнить выполнение на временная шкала GPU, который обновляет некоторые данные в период между периодами времени, когда они задаются с помощью корневого параметра, зная, что при установке он будет статическим.

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

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

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

Корневая сигнатура версии 1.0 продолжает работать без изменений, хотя приложения, которые перекомпилируют корневые сигнатуры, теперь по умолчанию будут использовать корневую подпись 1.1 (с возможностью принудительной версии 1.0, если это необходимо).

Статические и переменные флаги

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

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

typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS
{
    D3D12_DESCRIPTOR_RANGE_FLAG_NONE    = 0,
    D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE    = 0x1,
    D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE   = 0x2,
    D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE    = 0x4,
    D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8
} D3D12_DESCRIPTOR_RANGE_FLAGS;

typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS
{
    D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0,
    D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE    = 0x2,
    D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
    D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC  = 0x8
} D3D12_ROOT_DESCRIPTOR_FLAGS;

DESCRIPTORS_VOLATILE

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

Если флаг DESCRIPTORS_VOLATILE не задан, дескрипторы являются статическими. Флаг для этого режима отсутствует. Статические дескрипторы означают, что дескрипторы в куче дескрипторов, на которую указывает корневая таблица дескрипторов, были инициализированы к моменту установки таблицы дескрипторов в списке или пакете команд (во время записи), и дескрипторы нельзя изменить, пока список команд или пакет не завершит выполнение в последний раз. Для корневой сигнатуры версии 1.1 статические дескрипторы являются допущением по умолчанию, и при необходимости приложение должен указать флаг DESCRIPTORS_VOLATILE.

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

Если дескрипторы являются статическими, происходит другое изменение в поведении, которое требует установки флага DESCRIPTORS_VOLATILE. Доступ за пределы границ к любым представлениям буфера (в отличие от представлений Texture1D/2D/3D/Cube) является недопустимым и приводит к неопределенным результатам, включая возможный сброс устройства, а не возвращает значения по умолчанию для операций чтения или удаления операций записи. Цель удаления возможности приложений зависеть от аппаратного обеспечения проверки доступа за пределы границ заключается в том, чтобы позволить драйверам повысить уровень доступа статических дескрипторов до доступа к корневому дескрипторову, если они сочтут это более эффективным. Корневые дескрипторы не поддерживают проверку за пределами границ.

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

DATA_VOLATILE

Если этот флаг задан, данные, на которые указывают дескрипторы, могут быть изменены ЦП в любое время, за исключением случаев, когда список команд или пакеты, связывающие таблицу дескрипторов, были отправлены и не завершены. Это единственное поддерживаеме поведение корневой сигнатуры версии 1.0.

Флаг доступен как в флагах диапазона дескрипторов, так и в флагах корневого дескриптора.

DATA_STATIC_WHILE_SET_AT_EXECUTE

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

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

Основное различие между DATA_STATIC_WHILE_SET_AT_EXECUTE и DATA_VOLATILE заключается в том, DATA_VOLATILE драйвер не может определить, изменили ли копии данных в списке команд данные, на которые указывает дескриптор, без дополнительного отслеживания состояния. Таким образом, если, например, драйвер может вставить любые команды предварительной выборки данных в свой список команд (например, чтобы сделать доступ шейдера к известным данным более эффективным), DATA_STATIC_WHILE_SET_AT_EXECUTE сообщит драйверу, что ему нужно выполнить только предварительную выборку данных в момент, когда он задан с помощью SetGraphicsRootDescriptorTable, SetComputeRootDescriptorTable или одного из методов для задания представления буфера констант. Представление ресурсов шейдера или представление неупорядоченного доступа.

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

Флаг доступен как в флагах диапазона дескрипторов, так и в флагах корневого дескриптора.

DATA_STATIC

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

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

Флаг доступен как в флагах диапазона дескрипторов, так и в флагах корневого дескриптора.

Объединение флагов

За один раз можно указать не более одного из флагов ДАННЫХ, за исключением диапазонов дескрипторов Sampler, которые вообще не поддерживают флаги DATA, так как образцы не указывают на данные.

Отсутствие флагов ДАННЫХ для диапазонов дескрипторов SRV и CBV означает, что по умолчанию предполагается поведение DATA_STATIC_WHILE_SET_AT_EXECUTE. Причина, по которой это значение по умолчанию выбрано, а не DATA_STATIC, заключается в том, что DATA_STATIC_WHILE_SET_AT_EXECUTE, скорее всего, будет безопасным значением по умолчанию в большинстве случаев, но все же дает некоторые возможности оптимизации лучше, чем использование по умолчанию DATA_VOLATILE.

Отсутствие флагов DATA для диапазонов дескрипторов UAV означает, что по умолчанию предполагается поведение DATA_VOLATILE, учитывая, как правило, В БПЛА записываются.

DESCRIPTORS_VOLATILE нельзя объединить с DATA_STATIC, но можно объединить с другими флагами DATA. Причина, по которой DESCRIPTORS_VOLATILE можно объединить с DATA_STATIC_WHILE_SET_AT_EXECUTE, заключается в том, что переменные дескрипторы по-прежнему требуют, чтобы дескрипторы были готовы во время выполнения списка команд или выполнения пакета, а DATA_STATIC_WHILE_SET_AT_EXECUTE только обещает статическую ность в подмножестве выполнения списка команд или выполнения пакета.

Сводка по флагам

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

Допустимые параметры D3D12_DESCRIPTOR_RANGE_FLAGS Описание
Флаги не заданы Дескрипторы являются статическими (по умолчанию). Предположения по умолчанию для данных: для SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE и для UAV: DATA_VOLATILE. Эти значения по умолчанию для SRV/CBV будут безопасно соответствовать шаблонам использования для большинства корневых сигнатур.
DATA_STATIC Дескрипторы и данные являются статическими. Это увеличивает потенциал оптимизации драйвера.
DATA_VOLATILE Дескрипторы являются статическими, а данные являются переменными.
DATA_STATIC_WHILE_SET_AT_EXECUTE Дескрипторы являются статическими, а данные — статическими, а заданы при выполнении.
DESCRIPTORS_VOLATILE Дескрипторы являются переменными, и по умолчанию делаются предположения о данных: для SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE и для UAV: DATA_VOLATILE.
DESCRIPTORS_VOLATILE | DATA_VOLATILE Дескрипторы и данные являются переменными, эквивалентными корневой сигнатуре 1.0.
DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE Дескрипторы являются переменными, но обратите внимание, что по-прежнему не позволяет изменять их во время выполнения списка команд. Таким образом, можно объединить дополнительное объявление о том, что данные являются статическими во время задания через корневую таблицу дескриптора во время выполнения. Базовые дескрипторы фактически являются статическими дольше, чем данные будут статическими.

 

Допустимые параметры D3D12_ROOT_DESCRIPTOR_FLAGS Описание
Флаги не заданы Предположения по умолчанию для данных: для SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE и для UAV: DATA_VOLATILE. Эти значения по умолчанию для SRV/CBV будут безопасно соответствовать шаблонам использования для большинства корневых сигнатур.
DATA_STATIC Данные являются статическими, что является наилучшим потенциалом для оптимизации драйвера.
DATA_STATIC_WHILE_SET_AT_EXECUTE Данные являются статическими, а заданы при выполнении.
DATA_VOLATILE Эквивалент корневой сигнатуры 1.0.

 

Сводка по API версии 1.1

Следующие вызовы API позволяют включить версию 1.1.

Перечисления

Эти перечисления содержат ключевые флаги для указания дескриптора и волатильности данных.

  • D3D_ROOT_SIGNATURE_VERSION : идентификаторы версий.
  • D3D12_DESCRIPTOR_RANGE_FLAGS : диапазон флагов, определяющих, являются ли дескрипторы или данные переменными или статическими.
  • D3D12_ROOT_DESCRIPTOR_FLAGS : диапазон флагов, аналогичный D3D12_DESCRIPTOR_RANGE_FLAGS, за исключением того, что к корневым дескрипторам применяются только флаги данных.

Структуры

Обновленные структуры (начиная с версии 1.0) содержат ссылки на флаги волатильности и статики.

Функции

Перечисленные здесь методы заменяют исходные функции D3D12SerializeRootSignature и D3D12CreateRootSignatureDeserializer , так как они предназначены для работы с любой версией корневой сигнатуры. Сериализованная форма передается в API CreateRootSignature . Если шейдер был создан с корневой сигнатурой, скомпилированный шейдер уже будет содержать сериализованную корневую сигнатуру.

Методы

Интерфейс ID3D12VersionedRootSignatureDeserializer создается для десериализации структуры данных корневой сигнатуры.

Вспомогательные структуры

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

  • CD3DX12_DESCRIPTOR_RANGE1
  • CD3DX12_ROOT_PARAMETER1
  • CD3DX12_STATIC_SAMPLER1
  • CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC

См . раздел Вспомогательные структуры и функции для D3D12.

Последствия нарушения флагов статической активности

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

Уровень отладки имеет параметры проверки того, что приложения выполняют свои обещания, включая обещания по умолчанию, которые поставляются с использованием корневой подписи версии 1.1 без установки флагов.

Управление версиями

При компиляции корневых сигнатур, присоединенных к шейдерам, более новые компиляторы HLSL по умолчанию компилируют корневую сигнатуру в версии 1.1, тогда как старые компиляторы HLSL поддерживают только 1.0. Обратите внимание, что корневые подписи версии 1.1 не будут работать в ОС, которые не поддерживают корневую сигнатуру 1.1.

Версия корневой сигнатуры, скомпилированная с помощью шейдера, может быть принудительно установлена в определенной версии с помощью /force_rootsig_ver <version>. Принудительное применение версии будет успешным, если компилятор сможет сохранить поведение корневой сигнатуры, скомпилированной в принудительной версии, например путем удаления неподдерживаемых флагов в корневой сигнатуре, которые служат только для оптимизации, но не влияют на поведение.

Таким образом приложение может, например, компилировать корневую сигнатуру 1.1 в версии 1.0 и 1.1 при сборке приложения и выбрать соответствующую версию во время выполнения в зависимости от уровня поддержки ОС. Однако для приложения было бы наиболее эффективно компилировать корневые сигнатуры по отдельности (особенно если требуется несколько версий) отдельно от шейдеров. Даже если шейдеры изначально не компилируются с присоединенной корневой сигнатурой, преимущество проверки компилятором совместимости корневой сигнатуры с шейдером можно сохранить с помощью /verifyrootsignature параметра компилятора. Позже во время выполнения psos можно создать с помощью шейдеров, в которых нет корневых сигнатур при передаче нужной корневой сигнатуры (возможно, соответствующей версии, поддерживаемой ОС) в качестве отдельного параметра.

Создание корневой подписи

Корневые подписи

Определение корневых подписей в HLSL