Skip to main content
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. 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)

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._
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 :
  2. Triangle 1 :
  3. Triangle 2 :
  4. Triangle 3 :
Diagramme d'un nœud de triangles, montrant cinq sommets reliés implicitement pour former quatre triangles. 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.

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. 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. 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). , , , , 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 , et non à l’ordre implicite du triangle 1 dans le matériel . 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)

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

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

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)
Last modified on October 6, 2026