> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Conception matérielle du lancer de rayons

> Conception matérielle du lancer de rayons

Intégré directement dans chaque processeur de groupe de travail (WGP) des consoles XBOX Series se trouve un puissant matériel à fonction fixe conçu pour accélérer le processus de traversée des rayons dans les structures d'accélération de hiérarchie de volumes englobants (BVH).

Chaque bloc de données de texture (TD) peut effectuer quatre tests d'intersection rayon/boîte englobante alignée sur les axes (AABB) par cycle d'horloge, ou un test d'intersection rayon/triangle par cycle d'horloge. Le nombre de blocs TD des consoles XBOX Series est de 20 (pour la XBOX Series S) et de 56 (pour la XBOX Series X). Cela correspond aux débits « de pointe » de tests d'intersection présentés dans les tableaux suivants.

| Console | Débit de pointe des tests d'intersection rayon/AABB |
| - | - |
| XBOX Series S | 1563 MHz × 10 WGP × 2 TD par WGP × 4 AABB par requête = *125,0 milliards de tests rayon/AABB par seconde* |
| XBOX Series X | 1825 MHz × 26 WGP × 2 TD par WGP × 4 AABB par requête = *379,6 milliards de tests rayon/AABB par seconde* |

| Console | Débit de pointe des tests d'intersection rayon/triangle |
| - | - |
| XBOX Series S | 1563 MHz × 10 WGP × 2 TD par WGP × 1 triangle par requête = *31,26 milliards de tests rayon/triangle par seconde* |
| XBOX Series X | 1825 MHz × 26 WGP × 2 TD par WGP × 1 triangle par requête = *94,9 milliards de tests rayon/triangle par seconde* |

L'accès aux fonctionnalités de lancer de rayons du TD est très semblable à la façon dont l'échantillonnage et le filtrage de textures sont effectués aujourd'hui.

Deux nouvelles instructions ont été ajoutées au jeu d'instructions du GPU.

1. image\_bvh\_intersect\_ray
2. image\_bvh64\_intersect\_ray

Ces instructions ne diffèrent que par la largeur de l'adresse prise en entrée : 32 bits dans le cas d'image\_bvh\_intersect\_ray et 64 bits pour image\_bvh64\_intersect\_ray. La version 32 bits de l'instruction peut adresser des BVH d'une taille allant jusqu'à 32 Go; dans la plupart des cas, il est donc peu probable que la version « bvh64 » soit nécessaire.

Les entrées de l'instruction image\_bvh\_intersect\_ray sont les suivantes : image\_bvh\_intersect\_ray vgpr\_output\[4], vgpr\_input\[11] et sgpr\_resource\[4].

Les 11 registres vectoriels à usage général (VGPR) fournis en entrée sont présentés dans le tableau suivant.

\| Index de VGPR | Données | Description | |---|---| | 0 | node\_pointer (u32) | Les bits 2:0 indiquent le type de test d'intersection de rayon demandé (voir ci-dessous). Les bits 31:3 forment une adresse de 29 bits, alignée sur 64 octets; par exemple, 0 = 0x0, 1 = 0x40 et 2 = 0x80, par rapport à l'adresse de base du BVH. | | 1 | ray\_extent (f32) | La distance maximale (habituellement appelée « t ») à laquelle les intersections peuvent se produire. Toute intersection potentielle à une distance supérieure à ray\_extent n'est pas considérée comme une intersection, et un « échec » est retourné à la place. | | 2 | ray\_origin.x (f32) | La coordonnée x de la position de départ du rayon. | | 3 | ray\_origin.y (f32) | La coordonnée y de la position de départ du rayon. | | 4 | ray\_origin.z (f32) | La coordonnée z de la position de départ du rayon. | | 5 | ray\_direction.x (f32) | La composante x de la direction du rayon. | | 6 | ray\_direction.y (f32) | La composante y de la direction du rayon. | | 7 | ray\_direction.z (f32) | La composante z de la direction du rayon. | | 8 | ray\_inverse\_direction.x (f32) | L'inverse de la composante x de la direction du rayon. Les valeurs infinies sont valides si la composante directionnelle sur cet axe est 0.0f. | | 9 | ray\_inverse\_direction.y (f32) | L'inverse de la composante y de la direction du rayon. Les valeurs infinies sont valides si la composante directionnelle sur cet axe est 0.0f. | | 10 | ray\_inverse\_direction.z (f32) | L'inverse de la composante z de la direction du rayon. Les valeurs infinies sont valides si la composante directionnelle sur cet axe est 0.0f. |

Comme l'adresse de 29 bits de node\_pointer est en fait exprimée en multiples de 64 octets, la version 32 bits d'image\_bvh\_intersect\_ray peut adresser des BVH d'une taille allant jusqu'à 32 Go.

Un autre encodage « A16 » est également disponible, dans lequel ray\_direction et ray\_inverse\_direction sont encodés en float16. On peut y accéder en transmettant ray\_direction et ray\_inverse\_direction sous forme de float16\_t3 aux fonctions intrinsèques image\_bvh\_intersect\_ray ou image\_bvh64\_intersect\_ray. Nous n'avons pas constaté d'amélioration des performances avec cet encodage dans notre implémentation de la traversée.

Le rôle des quatre VGPR de sortie est décrit ci-dessous et varie selon le type de nœud interrogé.

### Descripteur de BVH

Le descripteur de texture BVH fait 128 bits et est organisé comme le montre le tableau suivant.

\| Champ | Bits | Taille | Données | |---|---| | Adresse de base du BVH | 39:0 | 40 | Adresse de base du BVH : alignée sur 256 octets. Par exemple, 0 = 0x0, 1 = 0x100 et 2 = 0x200. | | Inutilisé | 54:40 | 15 | Doit être zéro. | | Quantité d'agrandissement de la boîte | 62:55 | 8 | Nombre d'ULP à ajouter pendant un test rayon-boîte, encodé sous forme d'entier non signé. | | Tri des boîtes activé | 63 | 1 | Indique si les résultats des tests rayon/AABB doivent être triés. | | Taille | 105:64 | 42 | Nombre de nœuds du BVH moins 1. Impose une vérification des limites lors de l'accès. | | Inutilisé | 119:106 | 17 | Doit être zéro. | | Mode de retour des triangles | 120 | 1 | 0 : Mode de retour des triangles 0. 1 : Mode de retour des triangles 1. Plus d'informations dans une section ultérieure. | | Inutilisé | 122:121 | 2 | Doit être zéro. | | Grandes pages | 123 | 1 | Indique que toutes les pages mémoire utilisées sont inférieures ou égales à 64 Ko. Comme le pilote XBOX ne prend pas en charge les tailles de page inférieures à 64 Ko pour l'accès GPU, cette valeur doit toujours être 1. | | Type | 127:124 | 4 | Doit être défini à 0x8. |

## Types de nœuds BVH

L'instruction d'intersection de rayon décrite précédemment ne prend pas la géométrie (AABB ou triangles) en entrée au moyen de VGPR. Une adresse de 32 bits (« node\_pointer ») indique plutôt le nœud du BVH sur lequel effectuer le test d'intersection. L'avantage de cette approche est que l'opération mémoire et le test d'intersection peuvent être fusionnés en une seule opération par le TD. Le plus grand nœud faisant 128 octets, l'autre approche aurait consisté à charger, stocker et transmettre l'équivalent de 32 VGPR de charge utile de « géométrie » supplémentaire, en plus des 11 VGPR déjà utilisés pour les données du rayon. L'occupation aurait été fortement affectée par la nécessité de fournir jusqu'à l'équivalent de 43 VGPR en entrée à une instruction image\_bvh\_intersect\_ray.

Par conséquent, le matériel comprend nativement trois formats prescrits de nœuds BVH.

1. Nœud AABB FP16 (stockant 4 AABB) : 64 octets
2. Nœud AABB FP32 (stockant 4 AABB) : 128 octets
3. Nœud de triangles (stockant jusqu'à 4 triangles) : 64 octets

Les trois types de nœuds doivent être alignés sur 64 octets.

### Format du nœud de triangles (types de nœuds 0, 1, 2 et 3)

<Note>
  La section suivante est exacte en ce qui concerne la prise en charge matérielle; toutefois, il a été décidé dans XDXR de n'utiliser que deux triangles par nœud feuille et de stocker des métadonnées dans les entrées restantes.\_
</Note>

Le format du nœud de triangles stocke cinq sommets reliés implicitement pour former jusqu'à 4 triangles. La connectivité implicite entre V0, V1, V2, V3 et V4 n'est pas configurable et est la suivante.

1. Triangle 0 : { V0, V1, V2 }
2. Triangle 1 : { V1, V3, V2 }
3. Triangle 2 : { V2, V3, V4 }
4. Triangle 3 : { V2, V4, V0 }

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/rt-trianglenode.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=e7e8db72abe9215d85d31dde74702abe" alt="Diagramme d'un nœud de triangles, montrant cinq sommets reliés implicitement pour former quatre triangles." width="1051" height="912" data-path="images/gdk/features/graphics/rt-trianglenode.png" />

| Octets | Données |
| - | - |
| 11:0 | V0.xyz (3xfloat32) |
| 23:12 | V1.xyz (3xfloat32) |
| 35:24 | V2.xyz (3xfloat32) |
| 47:36 | V3.xyz (3xfloat32) |
| 59:48 | V4.xyz (3xfloat32) |
| 63:60 | ID de triangle (u32) |

Le TD effectue un test d'intersection rayon/triangle sur un seul des quatre triangles stockés dans le nœud, ce qui diffère du comportement des tests rayon/AABB, où les quatre AABB sont testés. Le triangle à tester parmi les quatre est indiqué par les 3 bits de poids faible de « node\_pointer » lors de l'appel d'image\_bvh\_intersect\_ray. Ces valeurs sont présentées dans le tableau suivant.

| Valeur | Type de nœud |
| - | - |
| 0 | Test d'intersection rayon/triangle sur le triangle 0 |
| 1 | Test d'intersection rayon/triangle sur le triangle 1 |
| 2 | Test d'intersection rayon/triangle sur le triangle 2 |
| 3 | Test d'intersection rayon/triangle sur le triangle 3 |
| 4 | Test d'intersection rayon/AABB sur quatre AABB FP16 |
| 5 | Test d'intersection rayon/AABB sur quatre AABB FP32 |
| 6 | Réservé |
| 7 | Réservé |

#### Données retournées par l'intersection

Lorsque le « mode de retour des triangles » du descripteur de BVH est défini à 0, les quatre VGPR retournés contiennent les données présentées dans le tableau suivant.

| VGPR | Données | Description |
| - | - | - |
| 0 | t\_num (f32) | Le numérateur de la distance « t » jusqu'à l'intersection. |
| 1 | t\_denom (f32) | Le dénominateur de la distance « t » jusqu'à l'intersection. La distance d'intersection est calculée comme t\_num/t\_denom. |
| 2 | triangle\_id (u32) | Retourne l'ID de triangle du nœud (63:60) plus l'index du triangle testé (0-3). |
| 3 | hit\_status (u32) | Retourne une valeur booléenne indiquant si le rayon a touché le triangle. 0 = échec, 1 = intersection. |

Lorsque le « mode de retour des triangles » du descripteur de BVH est défini à 1, les quatre VGPR retournés contiennent les données présentées dans le tableau suivant.

| VGPR | Données | Description |
| - | - | - |
| 0 | t\_num (f32) | Le numérateur de la distance « t » jusqu'à l'intersection. |
| 1 | t\_denom (f32) | Le dénominateur de la distance « t » jusqu'à l'intersection. La distance d'intersection est calculée comme t\_num/t\_denom. |
| 2 | i\_num (u32) | Le numérateur de la valeur « I » nécessaire à l'interpolation barycentrique. Doit être divisé par t\_denom pour calculer la valeur « I » réelle. |
| 3 | j\_num (u32) | Le numérateur de la valeur « J » nécessaire à l'interpolation barycentrique. Doit être divisé par t\_denom pour calculer la valeur « J » réelle. |

L'état de l'intersection peut être déduit en calculant si (t\_num/t\_denom) est inférieur à ray\_extent.

En mode de retour des triangles 1, le champ « triangle\_id » du nœud BVH sert à remapper l'ordre des sommets tel qu'ils ont été stockés dans le nœud de triangles par rapport à l'ordre dans lequel ils ont été fournis au générateur de BVH. Par exemple, avec la mémoire tampon d'index suivante, cette séquence de quatre triangles et cinq sommets peut être stockée dans un seul nœud de triangles (où 0 = V0, 1 = V1, 2 = V2, 3 = V3 et 4 = V4).

{ 0, 1, 2 }, { 3, 2, 1 }, { 4, 2, 3 }, { 2, 4, 0 },

Cependant, les deuxième et troisième triangles sont des rotations de l'ordre implicite défini par le matériel. Le sommet commun (V2) est le 3e sommet du triangle 1 tel que défini par le matériel (V1,V3,V2), mais il est spécifié en deuxième position dans la mémoire tampon d'index d'entrée. En conséquence, les coordonnées barycentriques « I » et « J » doivent être relatives à l'entrée de la mémoire tampon d'index {3, 2, 1}, et non à l'ordre implicite du triangle 1 dans le matériel {1, 3, 2}.

Pour atténuer ce problème, les octets 63:60 du nœud de triangles définissent plutôt 4 ensembles de bits de « remappage » qui indiquent au matériel par rapport auquel des 3 sommets du triangle les coordonnées barycentriques I et J doivent être exprimées. L'interprétation des octets 63:60 à cette fin est présentée dans le tableau suivant.

\| Champ | Bits | Taille | Données | |---|---| | Triangle 0, sommet source de « I » | 1:0 | 2 | 0 : « I » est le poids barycentrique de *V0*. 1 : « I » est le poids barycentrique de *V1*. 2 : « I » est le poids barycentrique de *V2*. 3 : Inutilisé. | | Triangle 0, sommet source de « J » | 3:2 | 2 | 0 : « J » est le poids barycentrique de *V0*. 1 : « J » est le poids barycentrique de *V1*. 2 : « J » est le poids barycentrique de *V2*. 3 : Inutilisé. | | Inutilisé | 7:4 | 4 | 4 bits d'espace libre. Peuvent servir à n'importe quelle fin; aucune valeur particulière n'est requise. | | Triangle 1, sommet source de « I » | 9:8 | 2 | 0 : « I » est le poids barycentrique de *V1*. 1 : « I » est le poids barycentrique de *V3*. 2 : « I » est le poids barycentrique de *V2*. 3 : Inutilisé. | | Triangle 1, sommet source de « J » | 11:10 | 2 | 0 : « J » est le poids barycentrique de *V1*. 1 : « J » est le poids barycentrique de *V3*. 2 : « J » est le poids barycentrique de *V2*. 3 : Inutilisé. | | Inutilisé | 15:12 | 4 | 4 bits d'espace libre. Peuvent servir à n'importe quelle fin; aucune valeur particulière n'est requise. | | Triangle 2, sommet source de « I » | 17:16 | 2 | 0 : « I » est le poids barycentrique de *V2*. 1 : « I » est le poids barycentrique de *V3*. 2 : « I » est le poids barycentrique de *V4*. 3 : Inutilisé. | | Triangle 2, sommet source de « J » | 19:18 | 2 | 0 : « J » est le poids barycentrique de *V2*. 1 : « J » est le poids barycentrique de *V3*. 2 : « J » est le poids barycentrique de *V4*. 3 : Inutilisé. | | Inutilisé | 23:20 | 4 | 4 bits d'espace libre. Peuvent servir à n'importe quelle fin; aucune valeur particulière n'est requise. | | Triangle 3, sommet source de « I » | 25:24 | 2 | 0 : « I » est le poids barycentrique de *V2*. 1 : « I » est le poids barycentrique de *V4*. 2 : « I » est le poids barycentrique de *V0*. 3 : Inutilisé. | | Triangle 3, sommet source de « J » | 27:26 | 2 | 0 : « J » est le poids barycentrique de *V2*. 1 : « J » est le poids barycentrique de *V4*. 2 : « J » est le poids barycentrique de *V0*. 3 : Inutilisé. | | Inutilisé | 31:28 | 4 | 4 bits d'espace libre. Peuvent servir à n'importe quelle fin; aucune valeur particulière n'est requise. |

Puisque les bits de triangle\_id servent à remapper les coordonnées barycentriques vers les sommets requis, ils ne peuvent plus être utilisés pour stocker un ID de triangle de base. Comme un ID de triangle disponible est souvent nécessaire pour les calculs d'ombrage ultérieurs (par exemple, pour lire des données de sommets ou de primitives comme les coordonnées de texture (UV) et les normales), ces données devront être stockées dans une structure distincte et lues manuellement.

### Format du nœud AABB FP16 (type de nœud 4)

| Octets | Données |
| - | - |
| 3:0 | Pointeur de nœud enfant 0 (u32) |
| 7:4 | Pointeur de nœud enfant 1 (u32) |
| 11:8 | Pointeur de nœud enfant 2 (u32) |
| 15:12 | Pointeur de nœud enfant 3 (u32) |
| 21:16 | Boîte englobante 0 - xyz minimum (3xfloat16) |
| 27:22 | Boîte englobante 0 - xyz maximum (3xfloat16) |
| 33:28 | Boîte englobante 1 - xyz minimum (3xfloat16) |
| 39:34 | Boîte englobante 1 - xyz maximum (3xfloat16) |
| 45:40 | Boîte englobante 2 - xyz minimum (3xfloat16) |
| 51:46 | Boîte englobante 2 - xyz maximum (3xfloat16) |
| 57:52 | Boîte englobante 3 - xyz minimum (3xfloat16) |
| 63:58 | Boîte englobante 3 - xyz maximum (3xfloat16) |

### Format du nœud AABB FP32 (type de nœud 5)

| Octets | Données |
| - | - |
| 3:0 | Pointeur de nœud enfant 0 (u32) |
| 7:4 | Pointeur de nœud enfant 1 (u32) |
| 11:8 | Pointeur de nœud enfant 2 (u32) |
| 15:12 | Pointeur de nœud enfant 3 (u32) |
| 27:16 | Boîte englobante 0 - xyz minimum (3xfloat32) |
| 39:28 | Boîte englobante 0 - xyz maximum (3xfloat32) |
| 51:40 | Boîte englobante 1 - xyz minimum (3xfloat32) |
| 63:52 | Boîte englobante 1 - xyz maximum (3xfloat32) |
| 75:64 | Boîte englobante 2 - xyz minimum (3xfloat32) |
| 87:76 | Boîte englobante 2 - xyz maximum (3xfloat32) |
| 99:88 | Boîte englobante 3 - xyz minimum (3xfloat32) |
| 111:100 | Boîte englobante 3 - xyz maximum (3xfloat32) |
| 127:112 | 16 octets d'espace libre. Peuvent servir à n'importe quelle fin; aucune valeur particulière n'est requise. |
|  | |

#### Données retournées par l'intersection AABB FP16 et FP32

Si « Tri des boîtes activé » dans le descripteur de BVH est défini à 0, le tableau suivant décrit les 4 VGPR retournés et leur rôle.

| VGPR | Données | Description |
| - | - | - |
| 0 | Pointeur de nœud enfant 0 (u32) | Retourne le pointeur de nœud enfant 0 en cas d'intersection. Retourne 0xFFFFFFFF en cas d'échec. |
| 1 | Pointeur de nœud enfant 1 (u32) | Retourne le pointeur de nœud enfant 1 en cas d'intersection. Retourne 0xFFFFFFFF en cas d'échec. |
| 2 | Pointeur de nœud enfant 2 (u32) | Retourne le pointeur de nœud enfant 2 en cas d'intersection. Retourne 0xFFFFFFFF en cas d'échec. |
| 3 | Pointeur de nœud enfant 3 (u32) | Retourne le pointeur de nœud enfant 3 en cas d'intersection. Retourne 0xFFFFFFFF en cas d'échec. |

Si « Tri des boîtes activé » dans le descripteur de BVH est défini à 1, le tableau suivant décrit les 4 VGPR retournés et leur rôle.

| VGPR | Données | Description |
| - | - | - |
| 0 | Pointeur de nœud enfant touché le plus proche (u32) | Retourne le pointeur de nœud enfant correspondant à la plus proche des quatre boîtes touchées. Retourne 0xFFFFFFFF si aucune des quatre boîtes n'a été touchée. |
| 1 | Deuxième pointeur de nœud enfant touché le plus proche (u32) | Retourne le pointeur de nœud enfant correspondant à la deuxième plus proche des quatre boîtes touchées. Retourne 0xFFFFFFFF si une boîte ou moins a été touchée. |
| 2 | Troisième pointeur de nœud enfant touché le plus proche (u32) | Retourne le pointeur de nœud enfant correspondant à la troisième plus proche des quatre boîtes touchées. Retourne 0xFFFFFFFF si deux boîtes ou moins ont été touchées. |
| 3 | Quatrième pointeur de nœud enfant touché le plus proche (u32) | Retourne le pointeur de nœud enfant correspondant à la quatrième plus proche des quatre boîtes touchées. Retourne 0xFFFFFFFF si trois boîtes ou moins ont été touchées. |

## Informations supplémentaires

* Il n'est *pas* nécessaire que tous les threads actifs d'une vague demandent la même adresse de nœud ou le même type de nœud pour l'intersection. Certains threads peuvent demander un test d'intersection rayon/triangle, tandis que d'autres effectuent un test d'intersection AABB FP16 ou FP32 dans la même instruction.
* Toutes les opérations effectuées dans le TD utilisent la virgule flottante simple précision.
* Tous les tests d'intersection rayon/AABB et rayon/triangle sont étanches.
* Les voies inactives peuvent en grande partie être considérées comme « gratuites » et ne coûtent pas de cycles dans le TD. Une voie peut être rendue inactive de l'une des façons suivantes :
  * En utilisant le masque d'exécution (c'est-à-dire le contrôle de flux)
  * En définissant à NaN n'importe quelle composante des éléments suivants : direction du rayon, direction inverse du rayon, origine du rayon et étendue du rayon
  * En définissant à Inf n'importe quelle composante de l'élément suivant : origine du rayon

## Voir aussi

[Vue d'ensemble du lancer de rayons (et de DXR)](/fr-CA/build/core-features/graphics/newfeatures/raytracing/rt-overview)


## Related topics

- [Répertoire des rubriques NDA : liens actifs vers Microsoft Learn](/fr-CA/nda/nda-topic-directory.md)
- [Exemples du GDK](/fr-CA/home/setup-install/samples.md)
- [Accéder aux ressources et téléchargements du GDK](/fr/home/onboarding-access/access-resources.md)
- [Accéder aux ressources et aux téléchargements du GDK](/fr-CA/home/onboarding-access/access-resources.md)
- [Étapes du test de validation des supports](/fr/publishing/game-publishing/concepts/certification/certification-media-validation-test-steps.md)
