Использование корневой подписи
Корневая сигнатура — это определение произвольно упорядоченной коллекции таблиц дескриптора (включая их макет), корневых констант и корневых дескрипторов. Каждая запись имеет свои затраты к установленному максимуму, поэтому приложение может найти компромисс между количеством различных типов записей, которые будут включены в корневую сигнатуру.
Корневая сигнатура — это объект, который можно создать вручную в API. Все шейдеры в PSO должны быть совместимы с корневым макетом, указанным в PSO, или отдельные шейдеры должны содержать встроенные корневые макеты, которые соответствуют друг другу; в противном случае создание PSO завершится ошибкой. Одним из свойств корневой подписи является то, что шейдеры не должны знать об этом при создании, хотя корневые подписи также можно создавать непосредственно в шейдерах при необходимости. Существующие ресурсы шейдера не требуют каких-либо изменений, совместимых с корневыми сигнатурами. Модель шейдера 5.1 представлена для обеспечения дополнительной гибкости (динамическое индексирование дескрипторов из шейдеров) и может быть добавочно принято начиная с существующих ресурсов шейдера по мере необходимости.
Семантика списка команд
В начале списка команд корневая подпись не определена. Графические шейдеры имеют свою собственную корневую подпись, отличную от подписи вычислительного шейдера, каждая из которых независимо назначается в командном списке. Корневая подпись, установленная в списке команд или пакете, также должна соответствовать текущему набору PSO в Draw/Dispatch; в противном случае поведение не определено. Несоответствия временных корневых сигнатур перед вызовом "Рисование"/"Диспетчер" допустимы, например, если задается несовместимый PSO перед переключением на совместимую корневую сигнатуру, при этом при вызове 'Рисование'/'Диспетчер' они уже совместимы. Настройка PSO не изменяет корневую подпись. Приложение должно вызвать выделенный API для задания корневой подписи.
После того как в списке команд установлена корневая подпись, макет определяет набор привязок, который должно обеспечить приложение, а также какие PSO могут использоваться (скомпилированные с тем же макетом) для следующих вызовов отрисовки и отправки. Например, корневую подпись можно определить приложением, чтобы иметь следующие записи. Каждая запись называется слотом.
- [0] Встроенный дескриптор CBV (корневые дескрипторы)
- [1] Таблица дескриптора, содержащая 2 SRVs, 1 CBV и 1 UAV
- [2] Таблица дескрипторов, содержащая 1 сэмплер
- [3] 4x32-разрядная коллекция корневых констант
- [4] Таблица дескрипторов, содержащая неопределенное число SRVs
В этом случае, прежде чем получить возможность выполнения команды рисования/отправки, приложение должно задать соответствующие связывания для каждого из слотов [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.
Связанные разделы