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


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

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

Обзор

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

Приложения часто тривиально способны:

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

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

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

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

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

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

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

Следующие флаги являются частью корневой сигнатуры, чтобы позволить драйверам выбрать стратегию для оптимальной обработки отдельных корневых аргументов при их установке, а также внедрить те же предположения в объекты состояния конвейера (PSOs) при их первоначальной компиляции , так как корневая сигнатура является частью 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/Куб) является недопустимым и выдает неопределенные результаты, включая возможный сброс устройства, а не возвращая значения по умолчанию для операций чтения или удаления записей. Цель удаления возможности приложений зависеть от оборудования, не связанного с проверкой доступа, заключается в том, чтобы позволить драйверам повысить уровень доступа статических дескрипторов к корневому дескриптору, если они считают, что более эффективны. Корневые дескрипторы не поддерживают проверку границ.

Если приложения зависят от безопасного поведения доступа к памяти при доступе к дескрипторам, они должны пометить диапазоны дескрипторов, которые обращаются к этим дескрипторам как 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

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

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

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

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

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

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

Отсутствие флагов ДАННЫХ для диапазонов дескрипторов UAV означает, что предполагается поведение DATA_VOLATILE по умолчанию, учитывая, что обычно ВАВ записываются в.

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

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

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

Допустимые параметры 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.

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

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

Структуры

Обновленные структуры (начиная с версии 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