Préface: Cette question va venir d'un point de vue Direct3D, car c'est ce que je connais.
De toute évidence, nous subissons une légère surcharge chaque fois que nous modifions les tampons de sommet ou d'index dans Direct3D (c'est-à-dire avec IASetIndexBuffer
). Mais je suppose que si nous allouons un tampon d'index / sommet géant, nous finirons par devoir gérer la mémoire manuellement et nous retrouverons avec un problème de fragmentation (ou nous nous arrêterons pendant que nous échangerons toutes les données).
Alors, comment les moteurs commerciaux chargent-ils / déchargent-ils les données? Je penche en quelque sorte vers une approche basée sur un «package», donc un «package» de modèles a son propre tampon vertex / index que nous pouvons charger / décharger car le package n'est plus nécessaire; puis essayez de dessiner toutes les instances du même package ensemble.
Mais je serais intéressé d'entendre quelle est la façon acceptée / standard de gérer cela?
la source
Réponses:
Il existe un certain nombre de techniques différentes pour organiser les données, et de nombreux jeux en utilisent un mélange.
Pour la géométrie statique, il est préférable d'avoir moins d'IB et de VB individuels.
Traditionnellement, les jeux sont basés sur le «niveau», ce qui signifie que les ressources d'une section de jeu sont chargées, puis le jeu commence. Pour minimiser les temps de chargement, les informations sont idéalement organisées pour prendre en charge cela (c'est-à-dire tout charger pour le niveau aussi rapidement que possible sans chercher sur le support / disque), en reproduisant éventuellement les informations entre les niveaux. Dans cette approche, un schéma consiste à avoir un grand VB et IB pour un modèle ou une série de modèles, puis soumettre des sous-ensembles de celui-ci à dessiner.
Pour la génération Xbox 360 / PS 3, la quantité de RAM était assez petite par rapport à la taille des jeux, donc les moteurs sont devenus orientés `` streaming '', ce qui signifie qu'ils chargent le contenu dynamiquement au fur et à mesure que le joueur les parcourt. C'est ce qu'on appelle également une approche de «monde ouvert». Dans cette approche, le défi consiste à «découper» la géométrie en bits que vous pouvez charger en fonction d'indices spatiaux. Un autre défi, en particulier pour les plates-formes 32 bits, est de garantir que la mémoire ne devienne pas fragmentée (ou même la fragmentation de l'espace d'adressage virtuel) sur une longue période de temps - les jeux basés sur les niveaux réinitialisent souvent la mémoire entre les niveaux, ce que les moteurs de streaming ne peuvent pas faire. aussi facilement. Par conséquent, le regroupement dans une taille fixe ou un ensemble de tailles fixes pour les IB / VB qui ont été alloués et réutilisés en tant que pool est utile.
Pour la génération Xbox One / PS 4, il y a beaucoup de RAM à utiliser par rapport aux consoles précédentes, et beaucoup de cœurs supplémentaires, donc de nombreux jeux compressent agressivement leurs actifs, puis utilisent des cœurs de processeur "supplémentaires" pour les décompresser dans le Contexte. Avec l'espace d'adressage virtuel 64 bits, la fragmentation de l'espace d'adressage virtuel est moins préoccupante. Cette approche permet de réduire les temps de chargement, de bien emballer les actifs pour le téléchargement numérique et de prendre en charge le rendu en monde ouvert. Ici, l'approche de pool pour gérer les IB / VB est utilisée.
Il existe également une soumission de géométrie dynamique qui est souvent utilisée pour les terrains, les modèles déformables / destructibles, etc. Ce n'est pas efficace en termes de bande passante du bus GPU, donc les jeux ont souvent un mélange de géométrie statique et dynamique. Dans ce cas, le modèle de mise à jour Direct3D Map DISCARD signifie généralement que vous n'utilisez qu'un seul IB / VB (ou pour les scénarios de rendu multithread, deux IB / VB que vous échangez en remplissant / en rendant chaque trame).
la source