Requêtes

Dans Direct3D 12, les requêtes sont regroupées en tableaux de requêtes appelés tas de requêtes. Un segment de requête a un type qui définit les types valides de requêtes qui peuvent être utilisés avec ce tas.

Différences dans les requêtes de Direct3D 11 à Direct3D 12

Les types de requête suivants ne sont plus présents dans Direct3D 12, leurs fonctionnalités étant incorporées dans d’autres processus :

  • Requêtes d’événement : l’événement est désormais géré par des clôtures.
  • Requêtes d’horodatage disjoint : les horloges GPU peuvent être définies sur un état stable dans Direct3D 12 (voir la section Minutage ). Les comparaisons d’horloge GPU ne sont pas significatives si le GPU est inactif du tout entre les horodatages (appelé requête disjointe). Avec une puissance stable, deux requêtes d’horodatage émises à partir de différentes listes de commandes sont comparables de manière fiable. Deux horodatages dans la même liste de commandes sont toujours comparables de manière fiable.
  • Requêtes de statistiques de sortie de flux : dans Direct3D 12, il n’existe aucune requête de dépassement de sortie de flux unique (SO) pour tous les flux de sortie. Les applications doivent émettre plusieurs requêtes à flux unique, puis mettre en corrélation les résultats.
  • Requêtes de prédicat de sortie de flux et de prédicat d’occlusion : les requêtes (qui écrivent en mémoire) et la prédication (qui lit à partir de la mémoire) ne sont plus couplées, de sorte que ces types de requête ne sont pas nécessaires.

Un nouveau type de requête d’occlusion binaire a été ajouté à Direct3D 12. Cela permet aux stratégies de prédication qui se soucient uniquement de savoir si un objet a été entièrement obclé ou non (plutôt que le nombre de pixels qui ont été obstrués) de l’indiquer à l’appareil, qui peut être en mesure d’effectuer les requêtes plus efficacement.

Segments de requête

Les requêtes peuvent être de plusieurs types (D3D12_QUERY_HEAP_TYPE) et sont regroupées en segments de requête avant d’être envoyées au GPU.

Un nouveau type de requête D3D12_QUERY_TYPE_BINARY_OCCLUSION est disponible et agit comme D3D12_QUERY_TYPE_OCCLUSION, sauf qu’il retourne un résultat binaire 0/1 : 0 indique qu’aucun échantillon n’a réussi le test de profondeur et de gabarit, 1 indique qu’au moins un échantillon a réussi les tests de profondeur et de gabarit. Cela permet aux requêtes d’occlusion de ne pas interférer avec l’optimisation des performances GPU associée au test de profondeur/gabarit.

Création de segments de requête

Les API pertinentes pour créer des tas de requête sont l’énumération D3D12_QUERY_HEAP_TYPE, le D3D12_QUERY_HEAP_DESC de struct et la méthode CreateQueryHeap.

Le runtime principal vérifie que le type de tas de requête est un membre valide de l’énumération D3D12_HEAP_TYPE et que le nombre est supérieur à 0.

Chaque élément de requête individuel dans un tas de requête peut être démarré et arrêté séparément.

Les API permettant d’utiliser les tas de requête sont les D3D12_QUERY_TYPE d’énumération et les méthodes BeginQuery et EndQuery.

D3D12_QUERY_TYPE_TIMESTAMP est la seule requête qui prend en charge EndQuery uniquement. Tous les autres types de requête nécessitent BeginQuery et EndQuery.

La couche de débogage valide les éléments suivants :

  • Il est illégal de commencer une requête d’horodatage : vous ne pouvez qu’y mettre fin.
  • Il est illégal de commencer une requête deux fois sans la terminer (pour un élément donné). Pour les requêtes qui nécessitent à la fois le début et la fin, il est illégal de mettre fin à une requête avant le début correspondant (pour un élément donné).
  • Le type de requête passé à BeginQuery doit correspondre au type de requête passé à EndQuery.

Le runtime principal valide les éléments suivants :

  • BeginQuery ne peut pas être appelé sur une requête timestamp.

  • Pour les types de requête qui prennent en charge à la fois BeginQuery et EndQuery (tous à l’exception de timestamp), une requête pour un élément donné ne doit pas couvrir les limites de la liste de commandes.

  • ElementIndex doit être compris dans la plage.

  • Le type de requête est un membre valide de l’énumération D3D12_QUERY_TYPE .

  • Le type de requête doit être compatible avec le tas de requête. Le tableau suivant montre le type de tas de requête requis pour chaque type de requête :

    Type de requête Type de tas de requête
    D3D12_QUERY_TYPE_OCCLUSION D3D12_QUERY_HEAP_TYPE_OCCLUSION
    D3D12_QUERY_TYPE_BINARY_OCCLUSION D3D12_QUERY_HEAP_TYPE_OCCLUSION
    D3D12_QUERY_TYPE_TIMESTAMP D3D12_QUERY_HEAP_TYPE_TIMESTAMP
    D3D12_QUERY_TYPE_PIPELINE_STATISTICS D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 D3D12_QUERY_HEAP_TYPE_SO_STATISTICS

     

  • Le type de requête est pris en charge par le type de liste de commandes. Le tableau suivant indique les requêtes prises en charge sur les types de liste de commandes.

    Type de requête Types de liste de commandes pris en charge
    D3D12_QUERY_TYPE_OCCLUSION Direct
    D3D12_QUERY_TYPE_BINARY_OCCLUSION Direct
    D3D12_QUERY_TYPE_TIMESTAMP Direct, Compute et éventuellement Copy
    D3D12_QUERY_TYPE_PIPELINE_STATISTICS Direct
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 Direct
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 Direct
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 Direct
    D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 Direct

     

Extraction de données à partir d’une requête

La façon d’extraire des données d’une requête consiste à utiliser la méthode ResolveQueryData . ResolveQueryData fonctionne avec tous les types de mémoire (qu’il s’agisse de mémoire système ou de mémoire locale d’appareil), mais nécessite que la ressource de destination soit dans D3D12_RESOURCE_STATE_COPY_DEST.