> ## 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

Chaque Workgroup Processor (WGP) des consoles XBOX Series intègre directement un puissant matériel à fonction fixe conçu pour accélérer le parcours des rayons à travers 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 XBOX Series S) et de 56 (pour 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 | 1825MHz × 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 similaire à la manière dont l'échantillonnage et le filtrage des 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 pour 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) d'entrée sont présentés dans le tableau suivant.

\| Index VGPR | Données | Description | |---|---| | 0 | node\_pointer (u32) | Les bits 2:0 spécifient le type de test d'intersection de rayon demandé (voir ci-dessous). Les bits 31:3 constituent 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) | Distance maximale (généralement appelée « t ») à laquelle les impacts sont autorisés. Toute intersection potentielle à une distance supérieure à ray\_extent n'est pas considérée comme un impact, et un « échec » est renvoyé à la place. | | 2 | ray\_origin.x (f32) | Coordonnée x de la position de départ du rayon. | | 3 | ray\_origin.y (f32) | Coordonnée y de la position de départ du rayon. | | 4 | ray\_origin.z (f32) | Coordonnée z de la position de départ du rayon. | | 5 | ray\_direction.x (f32) | Composante x de la direction du rayon. | | 6 | ray\_direction.y (f32) | Composante y de la direction du rayon. | | 7 | ray\_direction.z (f32) | Composante z de la direction du rayon. | | 8 | ray\_inverse\_direction.x (f32) | 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) | 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) | 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. |

C'est parce que l'adresse de 29 bits de node\_pointer s'exprime en pratique en multiples de 64 octets que la version 32 bits de 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. Il est accessible en passant ray\_direction et ray\_inverse\_direction en tant que float16\_t3 aux 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 du parcours.

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 du BVH fait 128 bits et est organisé comme indiqué dans 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 égal à zéro. | | Valeur d'agrandissement des boîtes | 62:55 | 8 | Nombre d'ULP à ajouter lors d'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. Applique une vérification des limites lors des accès. | | Inutilisé | 119:106 | 17 | Doit être égal à 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 égal à zéro. | | Grandes pages | 123 | 1 | Indique que toutes les pages mémoire utilisées sont inférieures ou égales à 64 Ko. Étant donné que 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 sur 0x8. |

## Types de nœuds de 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 via des VGPR. Au lieu de cela, une adresse de 32 bits (« node\_pointer ») spécifie 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'approche alternative aurait consisté à charger, stocker et transmettre l'équivalent de 32 VGPR de charge utile « géométrique » supplémentaire, en plus des 11 VGPR déjà utilisés pour les données du rayon. L'occupation aurait été gravement affectée par la nécessité de fournir jusqu'à 43 VGPR en entrée d'une instruction image\_bvh\_intersect\_ray.

Par conséquent, le matériel comprend nativement trois formats prescrits de nœuds de 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 de nœud de triangles (types de nœud 0, 1, 2 et 3)

<Note>
  La section suivante reflète fidèlement 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 de 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 se présente comme suit.

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 du test rayon/AABB, où les quatre AABB sont testées. Le triangle à tester parmi les quatre est spécifié par les 3 bits de poids faible de « node\_pointer » lors de l'appel à 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 renvoyées par l'intersection

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

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

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

| VGPR | Données | Description |
| - | - | - |
| 0 | t\_num (f32) | Numérateur de la distance « t » jusqu'à l'intersection. |
| 1 | t\_denom (f32) | Dénominateur de la distance « t » jusqu'à l'intersection. La distance d'impact est calculée comme t\_num/t\_denom. |
| 2 | i\_num (u32) | 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) | 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 d'impact 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 de BVH sert à remapper l'ordre des sommets tels 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 le tampon d'index suivant, cette séquence de quatre triangles/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 le tampon d'index d'entrée. Par conséquent, les coordonnées barycentriques « I » et « J » doivent être relatives à l'entrée du 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. Utilisables à 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. Utilisables à 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. Utilisables à 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. Utilisables à n'importe quelle fin ; aucune valeur particulière n'est requise. |

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

### Format de 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 de 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. Utilisables à n'importe quelle fin ; aucune valeur particulière n'est requise. |
|  | |

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

Si l'option « Tri des boîtes activé » du descripteur de BVH est définie sur 0, le tableau suivant décrit les 4 VGPR renvoyés et leur rôle.

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

Si l'option « Tri des boîtes activé » du descripteur de BVH est définie sur 1, le tableau suivant décrit les 4 VGPR renvoyés et leur rôle.

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

## Informations supplémentaires

* Il n'est *pas* nécessaire que tous les threads actifs d'une wave 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 d'AABB FP16 ou FP32 dans la même instruction.
* Toutes les opérations effectuées au sein du TD utilisent la virgule flottante simple précision.
* Tous les tests d'intersection rayon/AABB et rayon/triangle sont étanches (watertight).
* Les voies inactives peuvent être considérées comme largement « gratuites » et ne consomment pas de cycles au sein du TD. Une voie peut être rendue inactive de l'une des manières suivantes :
  * En utilisant le masque d'exécution (c'est-à-dire le contrôle de flux)
  * En définissant sur NaN une composante quelconque des éléments suivants : direction du rayon, direction inverse du rayon, origine du rayon et étendue du rayon
  * En définissant sur Inf une composante quelconque de l'élément suivant : origine du rayon

## Voir aussi

[Vue d'ensemble du lancer de rayons (et de DXR)](/fr/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)
