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


Использование корневой подписи

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

Корневая сигнатура — это объект, который можно создать вручную в API. Все шейдеры в PSO должны быть совместимы с корневым макетом, указанным в PSO, в противном случае отдельные шейдеры должны включать встроенные корневые макеты, соответствующие друг другу; в противном случае создание PSO завершится ошибкой. Одно из свойств корневой сигнатуры заключается в том, что шейдеры не должны знать об этом при создании, хотя корневые подписи также могут создаваться непосредственно в шейдерах, если это необходимо. Существующие ресурсы шейдера не требуют изменений, чтобы обеспечить совместимость с корневыми сигнатурами. Модель шейдера 5.1 представлена для обеспечения дополнительной гибкости (динамическое индексирование дескрипторов из шейдеров) и может постепенно внедряться, начиная с существующих ресурсов шейдера по мере необходимости.

Семантика списка команд

В начале списка команд корневая сигнатура не определена. Графические шейдеры имеют отдельную корневую сигнатуру от вычислительного шейдера, каждый из которых независимо назначается в списке команд. Корневая сигнатура, заданная в списке команд или пакете, также должна соответствовать текущему заданному pso в draw/Dispatch; В противном случае поведение не определено. Временные несоответствия корневой сигнатуры перед рисованием или отправкой являются допустимыми, например, установка несовместимого pso перед переключением на совместимую корневую сигнатуру (если они совместимы к моменту вызова Draw/Dispatch). Настройка PSO не изменяет корневую сигнатуру. Приложение должно вызвать выделенный API для настройки корневой сигнатуры.

После установки корневой сигнатуры в списке команд макет определяет набор привязок, которые приложение должно предоставить, и какие объекты psos можно использовать (скомпилированные с тем же макетом) для следующих вызовов draw/dispatch. Например, приложение может определить корневую сигнатуру, чтобы иметь следующие записи. Каждая запись называется слотом.

  • [0] Встроенный дескриптор CBV (корневые дескрипторы)
  • [1] Таблица дескриптора, содержащая 2 srv, 1 CBV и 1 UAV.
  • [2] Таблица дескриптора, содержащая 1 дискретизатор.
  • [3] 4x32-разрядная коллекция корневых констант
  • [4] Таблица дескриптора, содержащая неопределенное число srv

В этом случае перед выпуском draw/Dispatch приложение должно задать соответствующую привязку для каждого из слотов [0..4], определенных приложением с текущей корневой сигнатурой. Например, в слоте [1] должна быть привязана таблица дескриптора, которая является непрерывной областью в куче дескрипторов, которая содержит (или будет содержать при выполнении) 2 SRV, 1 CBV и 1 UAV. Аналогичным образом таблицы дескрипторов должны быть заданы в слотах [2] и [4].

Приложение может одновременно изменять часть привязок корневой сигнатуры (остальные остаются неизменными). Например, если единственной вещью, которая должна меняться между отрисовками, является одна из констант в слоте [2], это все, что приложение должно повторно привязать. Как упоминалось ранее, версии драйвера или оборудования все состояния привязки корневой сигнатуры изменяются автоматически. Если корневая сигнатура изменяется в списке команд, все предыдущие привязки корневой сигнатуры устареют и все новые ожидаемые привязки должны быть заданы перед рисованием и отправкой; В противном случае поведение не определено. Если корневая сигнатура избыточно задана в тот же момент, существующие привязки корневой сигнатуры не устареют.

Семантика пакета

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

В следующем коде показан пример потока вызовов в пакет.

// Command List
...
pCmdList->SetGraphicsRootSignature(pRootSig); // new parameter space
MyEngine_SetTextures(); // bundle inherits descriptor table setting
MyEngine_SetAnimationFactor(fTime); // bundle inherits root constant
pCmdList->ExecuteBundle(...);
...
// Bundle
pBundle->SetGraphicsRootSignature(pRootSig); // same as caller, in order to inherits bindings
pBundle->SetPipelineState(pPS); 
pBundle->SetGraphicsRoot32BitConstant(drawConstantsSlot,0,drawIDOffset);
pBundle->Draw(...); // using inherited textures / animation factor
pBundle->SetGraphicsRoot32BitConstant(drawConstantsSlot,1,drawIDOffset);
pBundle->Draw(...);
...

При выходе из пакета любые изменения корневого макета и /или изменения привязки, внесенные пакетом, наследуются обратно в список вызывающих команд после завершения выполнения пакета.

Дополнительные сведения о наследовании см. в разделе Наследование состояния конвейера графикистатьи Управление состоянием графического конвейера в Direct3D 12.

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