|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||||
|
Membre habitué
![]() Mickaël LeclercIngénieur développement logiciels Inscription : août 2008 Messages : 223 ![]() |
Bien le bonjour,
Je recherche le meilleur moyen d'envoyer ma géometrie à OpenGL. Je m'explique : je stocke actuellement dans une classe Mesh un tableau dont chaque éléments est une information sur un sommet Code :
Code :
Code :
Kromagg
__________________
C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus) |
||||||
|
00
|
|
|
#2 |
![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 2 866 ![]() |
Bonjour
La première méthode ! Avec la seconde méthode, tu auras un tableau contigu en mémoire pour tes positions et un autre pour les autres informations. Lorsqu'un shader accédera aux informations d'un vertex, il devra donc accéder à 2 zones mémoire différentes. Avec la première méthode, les informations pour chaque vertex sont regroupées dans une même zone mémoire. Le GPU pourra donc mettre en cache une seule grande zone mémoire contenant toutes les informations pour plusieurs shaders. Les performances seront meilleures (recherche chez Mr Google avec les mots clés "gpu memory cache L1 L2 cache missing")
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur la programmation des GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. |
|
00
|
|
|
#3 |
|
Membre habitué
![]() Mickaël LeclercIngénieur développement logiciels Inscription : août 2008 Messages : 223 ![]() |
D'accord maintenant j'ai vu sur certains moteur 3D Open Source comme Ogre ou Irrlicht qu'il séparé un mesh en plusieurs sous-mesh, chaque sous-mesh correspondant à une partie du mesh principal avec un matérial différent.
Dans ce cas est-ce que je dois continuer avec un seul VBO ou utiliser un VBO par sous-mesh ? Kromagg
__________________
C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus) |
|
00
|
|
|
#4 |
|
Membre Expert
![]() ![]() |
Dans mon moteur (je pense que dans Ogre c'est pareil) je crée un VBO par submesh.
D'ailleurs le concept de découper en submesh est pour pouvoir appliquer des matériaux différents à un mesh. Si tu modélises avec 3DS Max ça correspond à la notion de submaterial
__________________
Si vous ne trouvez plus rien, cherchez autre chose... Chef de projet (et unique exécutant pour l'instant) pour Castor 3D |
|
|
00
|
|
|
#5 |
![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 2 866 ![]() |
Comme tu veux
L'intérêt de séparer en plusieurs meshs (1 pour chaque matériau) provient du fait qu'OpenGL est une machine à états et qu'il est préférable de minimiser ces changements d'états pour des raisons de performances. C'est ce que permet le fait de regrouper en fonction des matériaux (données organisées sous forme d'arbre en général). Autre point, les cartes graphiques sont plus efficaces pour transférer des blocs de données d'un coup que d'envoyer les données une par une. Créer des meshs contenant que quelques vertices diminue donc les performances (à l'extrême, on en revient à ce que faisait OpenGL avant les BO avec le mode immédiat ) A l'opposé, entre envoyer un très gros bloc de données ou plusieurs blocs moyens ne changera pas les performances (par exemple, 1 bloc de 100 Mo ou 2 blocs de 50 Mo).Donc tu peux créer plusieurs VBO (c'est plus simple pour la gestion des matériaux) mais fait attention que tes meshs contiennent suffisamment de données pour conserver les performances (j'ai pas de chiffres de taille de bloc, au pif je dirais de l'ordre de quelques Ko mais l'idéal serait de profiler et tester les 2 options) HS : les gpu récents peuvent faire de l'overlapping pour le gpu computing, c'est à dire transférer des données (up et down) en même temps que faire du calcul. Pour bénéficier de cette possibilité, on fragmente les données et les kernels : on envoie un bloc de données, on lance un kernel dessus et pendant ce temps, on envoie un second bloc de données, etc. Je ne sais pas si OpenGL utiliser ou permet cette approche (ou même si cela a un sens pour la 3D). Si quelqu'un en a entendu parler, je suis intéressé.
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur la programmation des GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. |
|
00
|
|
|
#6 |
![]() ![]() ![]() Alexandre LaurentÉtudiant Inscription : mai 2008 Messages : 6 560 ![]() |
Il est possible de faire un seul buffer, pour plusieurs mesh et sous meshes. De plus, c'est conseillé, car on enlève les changements d'état derrière.
Pour le dessin, on utilise ce buffer mais on y accède de multiples façons. Dans ce cas, les sous meshes servent à faire un tri par "matériaux" ou "techniques" permettant de diminuer les changements d'états. Du coup, l'accès au buffer n'est pas linéaire (par sous meshes), mais cela n'importe peu, car nous l'avons transféré qu'une fois et que nous ne changeons d'états que très peu souvent. Dans le programme, cela se reflètera par avoir une classe préparant le VBO (donc, acceptant une scène, lisant les donner et les transférant qu'une fois). Pour chaque objet et sous meshes, cette classe remplira des structures indiquant comment accéder aux buffers (informations tel que le stride / l'offset et le buffer utilisé). Finalement, lors du dessin, nous trions les objets de la scène comme nous voulons et utilisons la structure afin de faire les draw. Voilà comment je procède, dernièrement. (J'espère que je suis clair).
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi ![]() La rubrique a aussi un blog ! Ma page sur DVP Mon Portfolio Qui connaît l'erreur, connaît la solution. |
|
|
00
|
|
|
#7 | |
![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 2 866 ![]() |
Autre point que j'ai oublié de prendre en compte, c'est que si tu as un seul mesh, si tu souhaites ajouter un vertex en plein milieu, il faudra réallouer tout le bloc mémoire. Si tu travailles avec plusieurs meshs (plusieurs blocs mémoire), tu pourras réallouer que le bloc correspondant.
Cette remarque ne vaut évidement que si tu modifier dynamiquement tes meshs. Si tes meshs sont statiques, tu peux en créer qu'un seul sans problème. Citation:
Je conseille donc dans tous les cas d'organiser les données à l'avance pour regrouper les données utilisant les mêmes matériaux pour être proche en mémoire.
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur la programmation des GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. |
|
|
00
|
|
|
#8 | ||
![]() ![]() ![]() Alexandre LaurentÉtudiant Inscription : mai 2008 Messages : 6 560 ![]() |
Pour les caches, j'ai toujours du mal. Mais en théorie, si on ajoute un object entier à notre buffer, les sous meshes devrait être déjà groupé par le logiciel qui a crée le Mesh, donc cela devrait passer.
Ou alors, on désassemble chaque objet afin de les regrouper par sous mesh de matériel. Par rapport aux caches, mieux vaut faire des buffers interlacés: Citation:
Citation:
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi ![]() La rubrique a aussi un blog ! Ma page sur DVP Mon Portfolio Qui connaît l'erreur, connaît la solution. |
||
|
|
00
|
|
|
#9 |
![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 2 866 ![]() |
C'était la question initiale de Kromagg
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur la programmation des GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. |
|
00
|
|
|
#10 |
![]() ![]() ![]() Alexandre LaurentÉtudiant Inscription : mai 2008 Messages : 6 560 ![]() |
Pardon, j'avais compris autrement (plusieurs buffers du genre, un pour les positions, un autre pour les normales).
Sachant que la réponse de mon prof était : Peu importe
__________________
Vous souhaitez participer à la section Jeux ? Contactez-moi ![]() La rubrique a aussi un blog ! Ma page sur DVP Mon Portfolio Qui connaît l'erreur, connaît la solution. |
|
|
00
|
|
|
#11 |
![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 2 866 ![]() |
En effet, le plus souvent... peu importe
Je viens de vérifier sur la doc de NVIDIA (en particulier le Fermi Architecture Whitepapper). En fait, avant les Fermi, il n'y avait pas de cache L1/L2 Donc si on n'a pas de gpu > 4xx, aucun problème, on peut y aller à la barbare Le principe des caches est simple : tu as un cache pour chaque SM (stream multiprocessors). Si tes données pour chaque vertex sont dans des blocs mémoires différents, tu va charger en mémoire tes données de position (donc mettre en cache ce premier bloc de mémoire) puis charger en mémoires les autres informations (donc mettre en cache ce second bloc de mémoire). Chaque PE (processing element, 8 par SM) va ensuite faire son petit boulot sur les 8 premiers vertices. Pour les 8 seconds vertices, il faudra alors recharger le premier bloc mémoire puis le second et ainsi de suite. Si tes données sont contigues, le bloc mémoire contient toutes les données pour plusieurs séries de 8 vertices et il ne sera pas nécessaire de refaire des transferts GRAM -> L1/L2 pour chaque groupe de 8 vertices. C'est plus claire expliqué comme ça ? Pour info, à priori, les caches sont de 16 Ko (ou 64 Ko, configurable) pour L1. Ça serait la taille minimal des blocs pour ne pas perdre de performances.
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur la programmation des GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. |
|
00
|
|
|
#12 | |
|
Membre habitué
![]() Mickaël LeclercIngénieur développement logiciels Inscription : août 2008 Messages : 223 ![]() |
Citation:
C'est une discussion très intéressante et je vois que vous connaissez bien le sujet, notamment au niveau des architectures de GPU. Pour le moment je me concentre sur l'implémentation basique des mes fonctionnalités avant l'optimisation. Cela impliquera forcément un remaniement de certaines parties de l'architecture du moteur, comme je le vois avec la gestion des meshes.
__________________
C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus) |
|
|
00
|
|
|
#13 |
![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 2 866 ![]() |
Si tu écris correctement ton code avec un design correct, tu pourrais changer de structure sans difficulté. En particulier, fais bien attention au respect des différents principes de POO (et en premier le SRP).
Par exemple, différencies bien les classes qui manipules tes meshs : - le mesh proprement dit (donc un conteneur de vertices + d'autres informations) - un mesh loader (chargement des meshs depuis un fichier) - un mesh binder (envoi des données aux gpu) - un mesh render (affichage du mesh) et probablement autant de classes pour les submeshs (ou concevoir tes meshs pour qu'ils puissent être des conteneurs de meshs ?) Ensuite, tu utilises les templates (police et politque class) pour paramétrer les différentes structures de meshs et pouvoir les modifier facilement Bon courage PS : et oui, comme à chaque fois, je m'emballe sur les possibilités... m'écoutes pas trop et commence par faire quelque chose qui tourne, tu verras après pour les optimisations
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur la programmation des GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. |
|
00
|
|
|
#14 | |
|
Membre habitué
![]() Mickaël LeclercIngénieur développement logiciels Inscription : août 2008 Messages : 223 ![]() |
Citation:
Kromagg
__________________
C'est dans ses rêves que l'homme trouve la liberté cela fut, est et restera la vérité! (John Keating - Le cercle des poètes disparus) |
|
|
00
|
|
|
#15 | ||||
|
Invité régulier
![]() Développeur de jeux vidéo Inscription : juillet 2011 Messages : 9 ![]() |
Bonjour à tous,
Moi aussi j'ai une question en lien avec le présent sujet, j'ai lu quelque part (dommage je ne retrouve plus où *) que les cartes Nvidia accepte des Buffers de n'importe quel taille alors que les cartes ATI il faut impérativement que la taille soit un multiple de 32 bits. Par exemple : Code :
Code :
* Édit : J'ai trouvé où, c'était sur le site http://www.opengl.org/wiki/Vertex_Buffer_Object Merci à l'avance SuperGénie |
||||
|
|
00
|
|
|
#16 |
|
Expert Confirmé
![]() Inscription : septembre 2010 Messages : 1 349 ![]() |
Pour le coup des 32 octets, ce n'est qu'une suggestion de ATI et je pense qu'elle est aussi valable pour les NVidia. Maintenant, rajouter des données pour favoriser l'alignement dégrade aussi les performances puisqu'il faut faire transiter plus de données. Le bon choix est donc celui qui déchargera ton bottleneck actuel.
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com