Compartilhar via


Como usar uma assinatura raiz

A assinatura raiz é a definição de uma coleção arbitrariamente organizada de tabelas de descritor (incluindo seu layout), constantes raiz e descritores raiz. Cada entrada tem um custo para um limite máximo, portanto, o aplicativo pode trocar o saldo entre quantos de cada tipo de entrada a assinatura raiz conterá.

A assinatura raiz é um objeto que pode ser criado por especificação manual na API. Todos os sombreadores em um PSO devem ser compatíveis com o layout raiz especificado com o PSO, ou então os sombreadores individuais devem incluir layouts raiz inseridos que correspondam uns aos outros; caso contrário, a criação de PSO falhará. Uma propriedade da assinatura raiz é que os sombreadores não precisam saber sobre ela quando criados, embora as assinaturas raiz também possam ser criadas diretamente em sombreadores, se desejado. Os ativos de sombreador existentes não exigem que nenhuma alteração seja compatível com assinaturas raiz. O Modelo de Sombreador 5.1 é introduzido para fornecer alguma flexibilidade extra (indexação dinâmica de descritores de dentro de sombreadores) e pode ser adotado incrementalmente a partir de ativos de sombreador existentes, conforme desejado.

Semântica da Lista de Comandos

No início de uma lista de comandos, a assinatura raiz é indefinida. Os sombreadores gráficos têm uma assinatura raiz separada do sombreador de computação, cada um atribuído independentemente em uma lista de comandos. O conjunto de assinatura raiz em uma lista de comandos ou pacote também deve corresponder ao PSO definido no momento em Draw/Dispatch; caso contrário, o comportamento é indefinido. As incompatibilidades transitórias de assinatura raiz antes de Draw/Dispatch são boas , como definir um PSO incompatível antes de alternar para uma assinatura raiz compatível (desde que elas sejam compatíveis com o momento em que Draw/Dispatch for chamado). Definir um PSO não altera a assinatura raiz. O aplicativo deve chamar uma API dedicada para definir a assinatura raiz.

Depois que uma assinatura raiz é definida em uma lista de comandos, o layout define o conjunto de associações que o aplicativo deve fornecer e quais PSOs podem ser usados (aqueles compilados com o mesmo layout) para as próximas chamadas de desenho/expedição. Por exemplo, uma assinatura raiz pode ser definida pelo aplicativo para ter as entradas a seguir. Cada entrada é chamada de "slot".

  • [0] Um descritor CBV embutido (descritores raiz)
  • [1] Uma tabela de descritor contendo 2 SRVs, 1 CBVs e 1 UAV
  • [2] Uma tabela de descritor que contém 1 sampler
  • [3] Uma coleção de 4x32 bits de constantes raiz
  • [4] Uma tabela de descritor que contém um número não especificado de SRVs

Nesse caso, antes de poder emitir um Draw/Dispatch, espera-se que o aplicativo defina a associação apropriada para cada um dos slots [0..4] que o aplicativo definiu com sua assinatura raiz atual. Por exemplo, no slot [1], uma tabela de descritor deve ser associada, que é uma região contígua em um heap de descritor que contém (ou conterá em execução) 2 SRVs, 1 CBVs e 1 UAV. Da mesma forma, as tabelas de descritor devem ser definidas em slots [2] e [4].

O aplicativo pode alterar parte das associações de assinatura raiz por vez (o restante permanece inalterado). Por exemplo, se a única coisa que precisa mudar entre os sorteios for uma das constantes no slot [2], isso é tudo o que o aplicativo precisa para reassociar. Conforme discutido anteriormente, o driver/hardware atualiza todo o estado de associação de assinatura raiz conforme ele é modificado automaticamente. Se uma assinatura raiz for alterada em uma lista de comandos, todas as associações de assinatura raiz anteriores ficarão obsoletas e todas as associações recém-esperadas deverão ser definidas antes de Desenhar/Expedir; caso contrário, o comportamento é indefinido. Se a assinatura raiz for redundantemente definida como a mesma definida no momento, as associações de assinatura raiz existentes não se tornarão obsoletas.

Semântica de Pacote

Os pacotes herdam as associações de assinatura raiz da lista de comandos (as associações aos vários slots no exemplo de Lista de Comandos acima). Se um pacote precisar alterar algumas das associações de assinatura raiz herdadas, ele deverá primeiro definir a assinatura raiz como igual à lista de comandos de chamada (as associações herdadas não se tornam obsoletas). Se o pacote definir a assinatura raiz como diferente da lista de comandos de chamada, isso terá o mesmo efeito que alterar a assinatura raiz na lista de comandos descrita acima: todas as associações de assinatura raiz anteriores estão obsoletas e as associações recém-esperadas devem ser definidas antes de Desenhar/Expedir; caso contrário, o comportamento é indefinido. Se um pacote não precisar alterar nenhuma associação de assinatura raiz, ele não precisará definir a assinatura raiz.

O código a seguir mostra um exemplo de fluxo de chamada em um pacote.

// 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(...);
...

Saindo de um pacote, todas as alterações de layout raiz e/ou alterações de associação que um pacote faz são herdadas de volta à lista de comandos de chamada quando um pacote termina de ser executado.

Para obter mais informações sobre herança, consulte a seção Herança de estado do pipeline gráfico de Gerenciamento do estado do pipeline de gráficos no Direct3D 12.

Assinaturas raiz