Signature racine version 1.1

L’objectif de la signature racine version 1.1 est de permettre aux applications d’indiquer aux pilotes quand les descripteurs d’un tas de descripteurs ne changent pas ou si les descripteurs de données pointent vers ne changent pas. Cela permet aux pilotes d’effectuer des optimisations qui peuvent être possibles, sachant qu’un descripteur ou la mémoire vers laquelle il pointe est statique pendant un certain temps.

Vue d’ensemble

La signature racine version 1.0 permet aux applications de modifier librement le contenu des tas de descripteurs et la mémoire vers laquelle ils pointent à chaque fois que les listes/bundles de commandes qui les référencent sont potentiellement en cours de vol sur le GPU. Toutefois, très souvent, les applications n’ont pas besoin de la flexibilité nécessaire pour modifier les descripteurs ou la mémoire après l’enregistrement des commandes qui les référencent.

Les applications sont souvent en mesure de :

  • Configurez des descripteurs (et éventuellement la mémoire vers laquelle ils pointent) avant de lier des tables de descripteurs ou des descripteurs racines sur une liste de commandes ou un bundle.
  • Assurez-vous que ces descripteurs ne changeront pas tant que la liste /bundles de commandes qui les référencent n’aura pas terminé l’exécution pour la dernière fois.
  • Assurez-vous que les données vers laquelle pointent les descripteurs ne changent pas pendant la même durée.

Sinon, une application ne peut être en mesure d’honorer que les données ne changent pas pendant une durée plus courte dans le temps. En particulier, les données peuvent être statiques pour la fenêtre dans le temps pendant l’exécution de la liste de commandes qu’une liaison de paramètre racine (table de descripteur ou descripteur racine) pointe actuellement vers les données. En d’autres termes, une application peut souhaiter effectuer une exécution sur le gpu chronologie qui met à jour certaines données entre les périodes où elles sont définies via un paramètre racine, sachant que lorsqu’elle est définie, elle sera statique.

Si les descripteurs, ou les descripteurs de données pointant vers, ne changent pas, alors les pilotes d’optimisation spécifiques peuvent être spécifiques au fournisseur de matériel, et surtout, ils ne modifient pas le comportement autre que l’amélioration possible des performances. Préserver autant de connaissances que possible sur l’intention de l’application n’impose pas de fardeau aux applications.

Une optimisation est que de nombreux pilotes peuvent produire des accès à la mémoire plus efficaces par les nuanceurs s’ils connaissent les promesses qu’une application peut faire concernant la statique des descripteurs et des données. Par exemple, les pilotes peuvent supprimer un niveau d’indirection pour accéder à un descripteur dans un tas en le convertissant en descripteur racine si le matériel particulier n’est pas sensible à la taille de l’argument racine.

La tâche supplémentaire pour les développeurs qui utilisent la version 1.1 consiste à faire des promesses sur la volatilité et la statique des données dans la mesure du possible, afin que les pilotes puissent faire les optimisations qui sont logiques. Les développeurs n’ont pas à faire de promesses concernant la statique.

La signature racine version 1.0 continue de fonctionner à l’identique, même si les applications qui recompilent les signatures racines seront désormais par défaut la signature racine 1.1 (avec une option permettant de forcer la version 1.0 si vous le souhaitez).

Indicateurs statiques et volatiles

Les indicateurs suivants font partie de la signature racine pour permettre aux pilotes de choisir une stratégie permettant de gérer au mieux les arguments racine individuels lorsqu’ils sont définis, et d’incorporer les mêmes hypothèses dans des objets d’état de pipeline (PSO) lorsqu’ils sont compilés à l’origine, car la signature racine fait partie d’un bloc d’alimentation.

Les indicateurs suivants sont définis par l’application et s’appliquent aux descripteurs ou aux données.

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

Avec ce jeu d’indicateurs, les descripteurs d’un tas de descripteurs pointés vers une table de descripteur racine peuvent être modifiés par l’application à tout moment, sauf pendant que la liste de commandes/bundles qui lient la table de descripteur ont été envoyés et n’ont pas terminé leur exécution. Par instance, l’enregistrement d’une liste de commandes et la modification ultérieure des descripteurs dans un tas de descripteurs auquel elle fait référence avant d’envoyer la liste de commandes pour exécution sont valides. Il s’agit du seul comportement pris en charge de la signature racine version 1.0.

Si l’indicateur DESCRIPTORS_VOLATILE n’est pas défini, les descripteurs sont statiques. Il n’existe aucun indicateur pour ce mode. Les descripteurs statiques signifient que les descripteurs dans un tas de descripteurs pointés par une table de descripteur racine ont été initialisés au moment où la table de descripteur est définie sur une liste de commandes/un bundle (pendant l’enregistrement), et les descripteurs ne peuvent pas être modifiés tant que la liste de commandes/le bundle n’a pas terminé l’exécution de la dernière fois. Pour la signature racine version 1.1, les descripteurs statiques sont l’hypothèse par défaut et l’application doit spécifier l’indicateur DESCRIPTORS_VOLATILE si nécessaire.

Pour les bundles utilisant des tables de descripteurs avec des descripteurs statiques, les descripteurs doivent être prêts à partir du moment où le bundle est enregistré (par opposition au moment où le bundle est appelé), et ne pas changer tant que le bundle n’a pas terminé son exécution pour la dernière fois. Les tables de descripteurs pointant vers des descripteurs statiques doivent être définies lors de l’enregistrement de l’offre groupée et non héritées dans le bundle. Il est valide pour une liste de commandes d’utiliser une table de descripteur avec des descripteurs statiques qui ont été définis dans un bundle et retournés à la liste de commandes.

Lorsque les descripteurs sont statiques, un autre changement de comportement nécessite la définition de l’indicateur DESCRIPTORS_VOLATILE. Les accès hors limites à n’importe quelle vue mémoire tampon (par opposition aux vues Texture1D/2D/3D/Cube) ne sont pas valides et produisent des résultats non définis, y compris une réinitialisation possible de l’appareil, plutôt que de retourner des valeurs par défaut pour les lectures ou la suppression d’écritures. L’objectif de la suppression de la possibilité pour les applications de dépendre de la vérification d’accès hors limites du matériel est de permettre aux pilotes de choisir de promouvoir les accès de descripteurs statiques aux accès de descripteur racine s’ils le jugent plus efficace. Les descripteurs racines ne prennent pas en charge la vérification hors limites.

Si les applications dépendent d’un comportement sécurisé d’accès à la mémoire hors limites lors de l’accès aux descripteurs, elles doivent marquer les plages de descripteurs qui accèdent à ces descripteurs comme DESCRIPTORS_VOLATILE.

DATA_VOLATILE

Avec ce jeu d’indicateurs, les données pointées par les descripteurs peuvent être modifiées par le processeur à tout moment, sauf lorsque la liste de commandes/les bundles qui lient la table de descripteur ont été envoyés et n’ont pas terminé leur exécution. Il s’agit du seul comportement pris en charge de la signature racine version 1.0.

L’indicateur est disponible à la fois dans les indicateurs de plage de descripteurs et les indicateurs de descripteur racine.

DATA_STATIC_WHILE_SET_AT_EXECUTE

Avec ce jeu d’indicateurs, les données pointées par les descripteurs ne peuvent pas changer à partir du moment où le descripteur racine sous-jacent ou la table de descripteur est défini sur une liste/un bundle de commandes pendant l’exécution sur le chronologie GPU, et se terminant lorsque les dessins/distributions suivants ne référencent plus les données.

Avant qu’un descripteur racine ou une table de descripteur n’ait été défini sur le GPU, ces données peuvent être modifiées même par la même liste/bundle de commandes. Les données peuvent également être modifiées alors qu’un descripteur racine ou une table de descripteur pointant vers elles est toujours défini sur la liste/bundle de commandes, tant que les dessins/répartitions référencés sont terminés. Toutefois, cela nécessite que la table de descripteur soit à nouveau redirigée vers la liste de commandes avant la prochaine fois que le descripteur racine ou la table de descripteur est déréférencé. Cela permet au pilote de savoir que les données pointées par un descripteur racine ou une table de descripteur ont changé.

La différence essentielle entre DATA_STATIC_WHILE_SET_AT_EXECUTE et DATA_VOLATILE réside dans DATA_VOLATILE un pilote ne peut pas déterminer si les copies de données d’une liste de commandes ont modifié les données pointées par un descripteur, sans effectuer de suivi d’état supplémentaire. Par conséquent, si, pour instance, un pilote peut insérer n’importe quel type de commandes de pré-extraction de données dans sa liste de commandes (pour rendre l’accès du nuanceur aux données connues plus efficace, par exemple), DATA_STATIC_WHILE_SET_AT_EXECUTE indique au pilote qu’il doit uniquement effectuer une pré-extraction des données au moment où elles sont définies via SetGraphicsRootDescriptorTable, SetComputeRootDescriptorTable ou l’une des méthodes permettant de définir l’affichage de mémoire tampon constante, l’affichage des ressources du nuanceur ou l’affichage d’accès non ordonné.

Pour les bundles, la promesse que les données sont statiques lors de l’exécution s’applique de manière unique à chaque exécution du bundle.

L’indicateur est disponible à la fois dans les indicateurs de plage de descripteurs et les indicateurs de descripteur racine.

DATA_STATIC

Si cet indicateur est défini, les données pointées par les descripteurs ont été initialisées au moment où un descripteur racine ou une table de descripteur référençant la mémoire a été défini sur une liste de commandes/bundle pendant l’enregistrement, et les données ne peuvent pas être modifiées tant que la liste de commandes/le bundle n’a pas terminé l’exécution de la dernière fois.

Pour les bundles, la durée statique commence au paramètre de descripteur racine ou de table de descripteur pendant l’enregistrement du bundle, par opposition à l’enregistrement d’une liste de commandes appelante. En outre, une table de descripteur pointant vers des données statiques doit être définie dans le bundle et non héritée. Il est valide pour une liste de commandes d’utiliser une table de descripteur pointant vers des données statiques qui ont été définies dans un bundle et retournées à la liste de commandes.

L’indicateur est disponible à la fois dans les indicateurs de plage de descripteurs et les indicateurs de descripteur racine.

Combinaison d’indicateurs

L’un des indicateurs DATA peut tout au plus être spécifié à la fois, à l’exception des plages de descripteurs Sampler qui ne prennent pas en charge les indicateurs DATA du tout, car les échantillonneurs ne pointent pas vers les données.

L’absence d’indicateurs DATA pour les plages de descripteurs SRV et CBV signifie qu’un comportement par défaut DATA_STATIC_WHILE_SET_AT_EXECUTE est supposé. La raison pour laquelle cette valeur par défaut est choisie plutôt que DATA_STATIC est que DATA_STATIC_WHILE_SET_AT_EXECUTE est beaucoup plus susceptible d’être une valeur par défaut sécurisée dans la majorité des cas, tout en continuant à fournir une opportunité d’optimisation mieux que de faire la valeur par défaut à DATA_VOLATILE.

L’absence d’indicateurs DATA pour les plages de descripteurs DAV signifie qu’un comportement par défaut DATA_VOLATILE est supposé, étant donné que les UAV sont généralement écrits dans.

DESCRIPTORS_VOLATILE ne peut pas être combiné avec DATA_STATIC, mais peut être combiné avec les autres indicateurs DATA. La raison pour laquelle DESCRIPTORS_VOLATILE peut être combiné avec DATA_STATIC_WHILE_SET_AT_EXECUTE est que les descripteurs volatiles nécessitent toujours que les descripteurs soient prêts pendant l’exécution de la liste de commandes/du bundle, et DATA_STATIC_WHILE_SET_AT_EXECUTE ne fait que des promesses concernant la statique au sein d’un sous-ensemble de l’exécution de liste de commandes/bundle.

Résumé de l’indicateur

Les tableaux suivants résument les combinaisons d’indicateurs qui peuvent être utilisées.

Paramètres de D3D12_DESCRIPTOR_RANGE_FLAGS valides Description
Aucun indicateur défini. Les descripteurs sont statiques (valeur par défaut). Hypothèses par défaut pour les données : pour SRV/CBV : DATA_STATIC_WHILE_SET_AT_EXECUTE et pour les UAV : DATA_VOLATILE. Ces valeurs par défaut pour SRV/CBV s’adapteront en toute sécurité aux modèles d’utilisation de la majorité des signatures racines.
DATA_STATIC Les descripteurs et les données sont statiques. Cela optimise le potentiel d’optimisation des pilotes.
DATA_VOLATILE Les descripteurs sont statiques et les données sont volatiles.
DATA_STATIC_WHILE_SET_AT_EXECUTE Les descripteurs sont statiques et les données sont statiques lors de l’exécution.
DESCRIPTORS_VOLATILE Les descripteurs sont volatiles et des hypothèses par défaut sont faites concernant les données : pour SRV/CBV : DATA_STATIC_WHILE_SET_AT_EXECUTE, et pour les UAV : DATA_VOLATILE.
DESCRIPTORS_VOLATILE | DATA_VOLATILE Les descripteurs et les données sont volatiles, ce qui équivaut à La signature racine 1.0.
DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE Les descripteurs sont volatiles, mais notez que cela ne leur permet toujours pas de changer pendant l’exécution de la liste de commandes. Il est donc valide de combiner la déclaration supplémentaire indiquant que les données sont statiques lorsqu’elles sont définies via la table de descripteur racine pendant l’exécution . Les descripteurs sous-jacents sont en fait statiques plus longtemps que les données ne sont promises comme statiques.

 

Paramètres de D3D12_ROOT_DESCRIPTOR_FLAGS valides Description
Aucun indicateur défini. Hypothèses par défaut pour les données : pour SRV/CBV : DATA_STATIC_WHILE_SET_AT_EXECUTE et pour les UAV : DATA_VOLATILE. Ces valeurs par défaut pour SRV/CBV s’adapteront en toute sécurité aux modèles d’utilisation de la majorité des signatures racines.
DATA_STATIC Les données sont statiques, ce qui constitue le meilleur potentiel pour l’optimisation des pilotes.
DATA_STATIC_WHILE_SET_AT_EXECUTE Les données sont statiques lors de l’exécution.
DATA_VOLATILE Équivalent à La signature racine 1.0.

 

Résumé de l’API version 1.1

Les appels d’API suivants activent la version 1.1.

Énumérations

Ces énumérations contiennent les indicateurs clés pour spécifier le descripteur et la volatilité des données.

Structures

Les structures mises à jour (à partir de la version 1.0) contiennent des références aux indicateurs de volatilité/statiques.

Fonctions

Les méthodes répertoriées ici remplacent les fonctions D3D12SerializeRootSignature et D3D12CreateRootSignatureDeserializer , car elles sont conçues pour fonctionner sur n’importe quelle version de signature racine. Le formulaire sérialisé est celui qui est passé dans l’API CreateRootSignature . Si un nuanceur a été créé avec une signature racine, le nuanceur compilé contiendra déjà une signature racine sérialisée.

Méthodes

L’interface ID3D12VersionedRootSignatureDeserializer est créée pour désérialiser la structure de données de signature racine.

Structures d’assistance

Des structures d’assistance ont été ajoutées pour faciliter l’initialisation de certaines structures de la version 1.1.

  • CD3DX12_DESCRIPTOR_RANGE1
  • CD3DX12_ROOT_PARAMETER1
  • CD3DX12_STATIC_SAMPLER1
  • CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC

Reportez-vous à Structures et fonctions d’assistance pour D3D12.

Conséquences de la violation des indicateurs de statique

Le descripteur et les indicateurs de données décrits ci-dessus (ainsi que les valeurs par défaut impliquées par l’absence d’indicateurs particuliers) définissent une promesse de l’application au pilote concernant son comportement. Si une application ne respecte pas la promesse, il s’agit d’un comportement non valide : les résultats ne sont pas définis et peuvent être différents d’un pilote et d’un matériel à l’autre.

La couche de débogage dispose d’options permettant de valider que les applications respectent leurs promesses, y compris les promesses par défaut fournies avec l’utilisation de la signature racine version 1.1 sans définir d’indicateurs.

Version management

Lors de la compilation des signatures racines attachées à des nuanceurs, les compilateurs HLSL plus récents sont par défaut la compilation de la signature racine à la version 1.1, tandis que les anciens compilateurs HLSL prennent uniquement en charge la version 1.0. Notez que les signatures racines 1.1 ne fonctionnent pas sur les systèmes d’exploitation qui ne prennent pas en charge la signature racine 1.1.

La version de signature racine compilée avec un nuanceur peut être forcée à une version particulière à l’aide de /force_rootsig_ver <version>. Le forçage de la version réussit si le compilateur peut conserver le comportement de la signature racine compilée à la version forcée, par exemple en supprimant les indicateurs non pris en charge dans la signature racine qui servent uniquement à des fins d’optimisation, mais n’affectent pas le comportement.

De cette façon, une application peut, pour instance, compiler une signature racine 1.1 sur 1.0 et 1.1 lors de la génération de l’application et sélectionner la version appropriée au moment de l’exécution en fonction du niveau de prise en charge du système d’exploitation. Toutefois, il serait plus efficace d’espace pour une application de compiler des signatures racines individuellement (en particulier si plusieurs versions sont nécessaires), séparément des nuanceurs. Même si les nuanceurs ne sont pas initialement compilés avec une signature racine attachée, l’avantage de la validation du compilateur de la compatibilité de la signature racine avec un nuanceur peut être conservé à l’aide de l’option du /verifyrootsignature compilateur. Plus tard, au moment de l’exécution, les osS peuvent être créés à l’aide de nuanceurs qui ne contiennent pas de signatures racines tout en transmettant la signature racine souhaitée (peut-être la version appropriée prise en charge par le système d’exploitation) en tant que paramètre distinct.

Création d’une signature racine

Signatures racine

Spécification de signatures racine en langage HLSL