Dessin indirect
Le dessin indirect permet de transférer une partie du parcours de scène et de l’élimination de l’UC vers le GPU, ce qui permet d’améliorer les performances. La mémoire tampon de commandes peut être générée par le processeur ou le GPU.
- Signatures de commande
- Structures de mémoire tampon d’arguments indirects
- Création d’une signature de commande
- Rubriques connexes
Signatures de commande
L’objet de signature de commande (ID3D12CommandSignature) permet aux applications de spécifier un dessin indirect, en particulier en définissant les éléments suivants :
- Format de la mémoire tampon d’arguments indirects.
- Type de commande qui sera utilisé (à partir des méthodes ID3D12GraphicsCommandList DrawInstanced, DrawIndexedInstanced ou Dispatch).
- Ensemble de liaisons de ressources qui modifient l’appel par commande par rapport à l’ensemble hérité.
Au démarrage, une application crée un petit ensemble de signatures de commande. Au moment de l’exécution, l’application remplit une mémoire tampon avec des commandes (par le moyen que le développeur d’applications choisit). Les commandes contenant éventuellement l’état à définir pour les vues de mémoire tampon vertex, les vues de mémoire tampon d’index, les constantes racines et les descripteurs racines (SRV/UAV/CBV bruts ou structurés). Ces dispositions d’arguments ne sont pas spécifiques au matériel, afin que les applications puissent générer les mémoires tampons directement. La signature de commande hérite de l’état restant de la liste de commandes. Ensuite, l’application appelle ExecuteIndirect pour indiquer au GPU d’interpréter le contenu de la mémoire tampon d’arguments indirects selon le format défini par une signature de commande particulière.
Si la signature de commande modifie tous les arguments racines, elle est stockée dans la signature de commande en tant que sous-ensemble d’une signature racine.
Aucun état de signature de commande n’est renvoyé à la liste de commandes une fois l’exécution terminée. Cependant, après ExecuteIndirect, toutes les liaisons sont réinitialisées aux valeurs connues. En particulier :
- Si la signature de commande lie une mémoire tampon vertex à un emplacement particulier, après l’appel à ExecuteIndirect, une mémoire tampon vertex NULL est liée à cet emplacement.
- Si la signature de commande lie une mémoire tampon d’index, après l’appel à ExecuteIndirect, une mémoire tampon d’index NULL est liée.
- Si la signature de commande définit une constante racine, après l’appel à ExecuteIndirect, la valeur de la constante racine est définie sur 0.
- Si la signature de commande définit une vue racine (CBV/SRV/UAV), après l’appel à ExecuteIndirect, la vue racine est définie sur une vue NULL.
Exemple avec les signatures de commande : supposons qu’un développeur d’applications souhaite qu’une constante racine unique soit spécifiée par appel de dessin dans la mémoire tampon d’arguments indirects. L’application crée une signature de commande qui permet à la mémoire tampon d’arguments indirects de spécifier les paramètres suivants par appel de dessin :
- Valeur d’une constante racine.
- Arguments de dessin (nombre de vertex, nombre d’instances, etc.).
La mémoire tampon d’arguments indirects générée par l’application contient un tableau d’enregistrements de taille fixe. Chaque structure correspond à un appel de dessin. Chaque structure contient les arguments de dessin et la valeur de la constante racine. Le nombre d’appels de dessin est spécifié dans une mémoire tampon distincte visible par le GPU.
Voici un exemple de mémoire tampon de commandes générée par l’application :
Structures de mémoire tampon d’arguments indirects
Les structures suivantes définissent la façon dont des arguments particuliers apparaissent dans une mémoire tampon d’arguments indirects. Ces structures n’apparaissent dans aucune API D3D12. Les applications utilisent ces définitions lors de l’écriture dans une mémoire tampon d’arguments indirects (avec l’UC ou le GPU) :
- D3D12_DRAW_ARGUMENTS
- D3D12_DRAW_INDEXED_ARGUMENTS
- D3D12_DISPATCH_ARGUMENTS
- D3D12_VERTEX_BUFFER_VIEW
- D3D12_INDEX_BUFFER_VIEW
- D3D12_GPU_VIRTUAL_ADDRESS (synonyme typedef d’UINT64).
- D3D12_CONSTANT_BUFFER_VIEW
Création d’une signature de commande
Pour créer une signature de commande, utilisez les éléments d’API suivants :
- ID3D12Device ::CreateCommandSignature (génère une ID3D12CommandSignature)
- D3D12_INDIRECT_ARGUMENT_TYPE
- D3D12_INDIRECT_ARGUMENT_DESC
- D3D12_COMMAND_SIGNATURE_DESC
L’ordre des arguments dans une mémoire tampon d’arguments indirects est défini pour correspondre exactement à l’ordre des arguments spécifié dans le paramètre pArguments de D3D12_COMMAND_SIGNATURE_DESC. Tous les arguments d’un appel de dessin (graphisme)/répartition (calcul) au sein d’une mémoire tampon d’arguments indirects sont intégrés de façon compacte. Toutefois, les applications sont autorisées à spécifier un pas d’octet arbitraire entre les commandes de dessin/répartition dans une mémoire tampon d’arguments indirects.
La signature racine doit être spécifiée si et uniquement si la signature de commande modifie l’un des arguments racines.
Pour le SRV/UAV/CBV racine, l’application spécifie la taille en octets. La couche de débogage valide les restrictions suivantes sur l’adresse :
- CBV : l’adresse doit être un multiple de 256 octets.
- SRV/UAV brut : l’adresse doit être un multiple de 4 octets.
- SRV/UAV structuré : l’adresse doit être un multiple du pas d’octet de structure (déclaré dans le nuanceur).
Une signature de commande donnée est soit un dessin soit une signature de commande de calcul. Si une signature de commande contient une opération de dessin, il s’agit d’une signature de commande graphique. Sinon, la signature de commande doit contenir une opération de répartition, et il s’agit alors d’une signature de commande de calcul.
Les sections suivantes vous montrent quelques exemples de signatures de commande.
Aucun changement d’argument
Dans cet exemple, la mémoire tampon d’arguments indirects générée par l’application contient un tableau de structures de 36 octets. Chaque structure contient uniquement les cinq paramètres passés à DrawIndexedInstanced (plus des caractères de remplissage).
Le code permettant de créer la description de la signature de commande suit :
D3D12_INDIRECT_ARGUMENT_DESC Args[1];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 36;
ProgramDesc.NumArgumentDescs = 1;
ProgramDesc.pArguments = Args;
La disposition d’une structure unique dans une mémoire tampon d’arguments indirects est la suivante :
Octets | Description |
---|---|
0:3 | IndexCountPerInstance |
4:7 | InstanceCount |
8:11 | StartIndexLocation |
12:15 | BaseVertexLocation |
16:19 | StartInstanceLocation |
20:35 | Remplissage |
Constantes racines et mémoires tampons vertex
Dans cet exemple, chaque structure d’une mémoire tampon d’arguments indirects modifie deux constantes racines, modifie une liaison de mémoire tampon vertex et effectue une opération de dessin non indexée. Il n’y a pas d’éléments de remplissage entre les structures.
Le code permettant de créer la description de la signature de commande est :
D3D12_INDIRECT_ARGUMENT_DESC Args[4];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[0].Constant.RootParameterIndex = 2;
Args[0].Constant.DestOffsetIn32BitValues = 0;
Args[0].Constant.Num32BitValuesToSet = 1;
Args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[1].Constant.RootParameterIndex = 6;
Args[1].Constant.DestOffsetIn32BitValues = 0;
Args[1].Constant.Num32BitValuesToSet = 1;
Args[2].Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW;
Args[2].VertexBuffer.Slot = 3;
Args[3].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 40;
ProgramDesc.NumArgumentDescs = 4;
ProgramDesc.pArguments = Args;
La disposition d’une structure unique dans la mémoire tampon d’arguments indirects est la suivante :
Octets | Description |
---|---|
0:3 | Données pour l’index de paramètres racines 2 |
4:7 | Données pour l’index de paramètres racines 6 |
8:15 | Adresse virtuelle de VB à l’emplacement 3 (64 bits) |
16:19 | Taille de VB |
20:23 | Pas de VB |
24:27 | VertexCountPerInstance |
28:31 | InstanceCount |
32:35 | StartVertexLocation |
36:39 | StartInstanceLocation |
Rubriques connexes