performances opengl - C++ - Programmation
Marsh Posté le 30-01-2004 à 22:26:15
Hum
Bon
Alors deja, les glBegin(), glColor(), glVertex()=>Poubelle
definitivement
glArrayElement, c'est mieux, mais si je ne m'abuse, tes vertex sont toujours en memoire systeme. Ce qui est naze.
La meilleure solution, celle qui t'assureras le max de perf, c'est les extensions proprietaires. La fo que tu te farcisse les sites de nvidia et ati pour savoir ce qu'ils proposent, et quoi et dispo pour chaque carte. Apres tu te tapes les codepaths permettant de gerer ca en fonction de la carte graphique.
<pub>Direct3D roulaize</pub>
Marsh Posté le 30-01-2004 à 22:35:54
Donc le but du jeu est de mettre un maximum de choses dans la mémoire vidéo avant de commencer. Ok merci. Pour ce qui est des extensions je me demande si GL_ARB_vertex_program n'a pas justement ce but sans l'inconvénient d'être propriétaire (j'aimerais éviter dans un premier temps de multiplier les chemins de code)
Marsh Posté le 30-01-2004 à 22:36:41
ah ouais exact, y'a ca qui est sorti, tout a fait
fonce la dessus
Tout(/le maximum de) ce qui est statique (que tu touche pas quoi) doit etre en ram video pour des perfos au max
Marsh Posté le 30-01-2004 à 23:23:39
Malédiction, bien évidemment, ma voodoo2 ne supporte pas cette extension, allez quoi, un effort ma vieille, on se bouge ! Je vais donc me pencher aussi sur les glDrawElements et compagnie.
Autre petite question en passant: dans mon moteur actuel avec ses glVertex pas frais, je crois avoir remarqué que la fonction glBindTexture est très lourde en ressource. Bien sûr avec ce que tu m'as raconté il y a moyen de mettre ça en mémoire vidéo, mais pour ma culture personnelle et aussi pour la fierté de ma voodoo2, j'aimerais comprendre pourquoi.
Je pose le problème clairement:
Sur une carte ne supportant pas la multitexture, je dessine un objet à 32 faces toutes bumpmappées en deux passes.
Au début, pour essai, je dessinais chaque face deux fois (avec deux glBindTexture par face donc) puis je passais à la face suivante etc...
Maintenant je dessine mon objet une fois en entier (un seul glBindTexture) puis une deuxieme fois en entier (un autre glBindTexture)
Donc dans un cas 64 glBindTexture et dans l'autre 2.
Considerant toutes les opérations nécessaires pour dessiner un objet en entier 2 fois, je ne pensais pas que la deuxiement solution serait plus performante. Et pourtant elle l'est terriblement. Mystere ! Y aurait-il des déplacements de registres entiers dans la carte vidéo à chaque appel de glBindTexture ?
Merci pour les infos en tout cas, je vais prendre le temps de travailler.
ps: je précise sur une carte sans multitexture, car je avec, le probleme est réglé autrement plus facilement (et rapidement)
Marsh Posté le 30-01-2004 à 23:26:46
ben pour ta voodoo2 te casse pas, seules les cartes avec TnL embarquent les vtx dans la ram video
Alors y'a des trucs a savoir pour les perfos 3D:
->eviter d'envoyer sur l'AGP. Le moins qui transite, le mieux
->dessiner a coup de batch (mieux vaut un appel que 350)
->Minimiser les "state change" (changement de texture, de mode de rendu...)
Et >>>LE<<< truc a ne JAMAIS faire : lire qq chose se trouvant sur la carte video. JAMAIS. JURE LE !!!!!
c'est les bases a ne jamais perdre de vue
Marsh Posté le 30-01-2004 à 23:37:52
et avec une display list tu gagne avec tout ca?
moi ca mulitpli les perf par 12 en moyenne mais ca reste pour les objet statique
glArrayElement permet il me semble de passer uniquement un tableau en parametre et donc de reduire les acces a la pile
pour moin utiliser glBindTexture tu peut mettre tes textures dans une seule image et apres pendant le rendu tu les selectionnne avec glTextCoord2f
pense aussi a utiliser le cullfacing tant que tes faces sont dessiner dans le sens trigo histoire d'economiser le fillrate
sinon dans un moteur, ce qui te fera gangner un max en perf c'est la gestion de la partie physique avec un moteur de partitionnement spatial comme les octrees et les bsp trees
Marsh Posté le 30-01-2004 à 23:39:48
skelter a écrit : |
ca evite surtout de faire un appel au driver pour 2octets (et si le driver est pourri, d'envoyer 2 povs octets via l'agp. La c pareil, mieux vaut mettre des grandes que des petites touchettes)
Marsh Posté le 30-01-2004 à 23:41:35
ok, merci de l'info
Marsh Posté le 31-01-2004 à 00:11:55
Oui, pour le t&l je savais que c'était indispensable, et pour ce qui est de la texture, je pensais effectivement concentrer toutes mes faces sur une seule texture découpée en zone comme on voit souvent en fait dans les jeux.
Quant aux octrees, je ne me suis pas encore penché dessus. J'ai mon propre moteur physique qui marche assez bien pour ce que je lui demande en tout cas.
Merci pour les infos à tous les deux.
Je vous dirai si l'honneur de la voodoo 2 est sauf.
ps: en fait, je relis et je ne comprends pas encore comment marche glArrayElement par rapport à glVertex. Ok il donne l'emplacement d'un vertex mais en quoi est-il fondamentalement plus rapide car ce vertex doit d'une maniere ou d'une autre transiter par le port, non ?
Bon, j'arrete pour ce soir.
Marsh Posté le 31-01-2004 à 02:13:45
j'ai pas été zieuter, mais le modèle d'accès aux vertex est le vertexbuffer, le concept a été repris par l'ARB pour l'OpenGl 1.4/1.5 sais pu. (VBO: vertex buffer object)
problème: fo une carte récente.
donc, dans l'absolu, ce qui développera le maximum de performances pour une gf3/gf4ti/radeon/gf fx, ne devrait pas être supporté ou valable pour une voodoo².
chrisbk >> l'agp n'est pas un problème, personnellement je pense que tout mettre en ram vidéo n'est pas une solution, car tu pompes de la bande passante pour les unitées de textures.
electroniquement, une carte moderne doit être capable de faire des accès mémoire et agp en concurrence, donc je pense que le rendement max est généré par les textures en ram vidéo (forcément), et le vertexbuffer/indexbuffer en ram agp (ou uniquement l'indexbuffer en ram agp), comme ça tout se recouvre dans le temps...
mais bon pas encore faire des modèles de benchs....
Marsh Posté le 31-01-2004 à 02:26:38
bjone a écrit : |
je t'avouerais que je ne me preoccupe pas completement de ca, je laisse d3d se demerder (jlui dis que mon vb est static, et au diable)
Marsh Posté le 31-01-2004 à 02:34:33
t'inquiètes po, pour moi c'est pareil
--
sinon pour une voodoo 2, john_john tu devrais zieuter tout ce qui est code source de quake & co...
Marsh Posté le 31-01-2004 à 04:50:11
Citation : tu devrais zieuter tout ce qui est code source de quake & co |
mauvaise idée: Quake et Q II utilisent
glVertex.. A l'époque ça suffisait.
Va plutot sur developper.nvidia.com, il y a
des papiers et des idée sur tout. (certains trucs
sont vieux mais sont encore vrais, il faut juste multiplier les chiffres)
Et puis change de carte graphique.. Voodoo 2
ca fera pas grande différence si tu optimises ton
moteur pour ce genre de carte.. Tu n'auras pas de mal a trouver mieux pour vraiment pas cher avec des drivers OpenGL valables !
Grégory
Marsh Posté le 31-01-2004 à 11:26:07
Oui, changer de carte graphique bien-sûr, mais ce n'est pas vraiment mon problème, je dispose de trois ordos ici avec trois cartes graphiques très différentes: voodoo2, nforce1, radeon9700pro et je cherche où doivent se situer mes optimisations et où doivent se situer mes exigences en matiere de technologies. J'aimerais que mon programme marche sur un grand nombre de machines et pour l'instant je me dirige peu à peu vers un découpage en deux chemins de code: un optimisé multitexture et t&l (donc à partir des geforce1) et un autre sans tout ça, que j'aimerais baser sur les glArrayElement et autres pour gagner quand même en vitesse.
Mais pour ça j'aimerais comprendre l'avantage structurel des glArrayElement et autres par rapport à glVertex. J'imagine que cet avantage doit se situer au delà de la simplification de l'appel de fonction (d'autant plus si on compare à glVertex3fv et son unique argument)
Merci !
Marsh Posté le 31-01-2004 à 11:57:29
quand tu affiche genre 6 faces pour faire un cube ou un parallepipede qui representerait une piece, ca tourne a quel vitesse sur une voodoo 2?
je dis ca car un avec un moteur de partionnement spatiale meme avec 100 pieces dans ta map, ca sera a peine plus lent, donc tu imagine l'utilité et le fabuleux gain de perfs sur une grosse map, sans compter le gain cpu avec tout les calcul de collisions que tu n'aura pas a faire sur les faces qui ne sont pas a proximité de la camera(dans le cas d'un fps bien sur)
voila c'est juste pour dire qu'apres avoir fais quelques optim. sur le corps opengl, je pense que c'est plus sur la partie physique que l'on gagne en perf
Marsh Posté le 31-01-2004 à 12:35:26
Oui, je suis d'accord avec toi mais je cherche toutes les optimisations possibles. Pour ce qui est du partitionnement spatial, j'ai un truc simple qui consiste à ne calculer que ce qui est proche de l'objet, une sorte de clipping quoi qui concernerait les tests de collision entre les objets.
Les scènes que j'affiche sont très très ouvertes donc peu sensibles aux optimisations que tu proposes. Mais il me reste quand même à ne pas afficher les objets qui sont derrières la caméra, oui c'est à faire je n'en disconviens pas (tout à fait cher ami).
Marsh Posté le 31-01-2004 à 12:43:35
n'est afficher que ce qui est dans entre les plans de clipping proche et lointain, non? enfin c'est vrai qu'en ramenant vers moi le plan lointain je n'ai observer pratiquement aucune diff de perf (bizar?)
sinon si tes scenes sont tres ouvertes ==> octrees
Marsh Posté le 31-01-2004 à 13:50:56
si tu ramènes le plan lointain, tu améliore la précision sur le Z-buffer.
quelque soit ta configuration de plan proche/lointain, ce qui est demandé à la carte 3D (que ce soit en D3D ou en OpenGl) est effectué.
bien sûr tu économises en fill-rate (si énormément de surface est rejetée par le test contre le z-buffer et/ou le plan lointain), mais la charge géométrique est invariante.
c'est à toi de rejetter les objets hors-frustum en amont des appels OpenGl/D3D.
Marsh Posté le 31-01-2004 à 16:21:58
john_john a écrit : Oui, changer de carte graphique bien-sûr, mais ce n'est pas vraiment mon problème, je dispose de trois ordos ici avec trois cartes graphiques très différentes: voodoo2, nforce1, radeon9700pro et je cherche où doivent se situer mes optimisations et où doivent se situer mes exigences en matiere de technologies. J'aimerais que mon programme marche sur un grand nombre de machines et pour l'instant je me dirige peu à peu vers un découpage en deux chemins de code: un optimisé multitexture et t&l (donc à partir des geforce1) et un autre sans tout ça, que j'aimerais baser sur les glArrayElement et autres pour gagner quand même en vitesse. |
Ce que j'essayais de t'expliquer c'est qu'optimiser pour une voodoo 2 est de la perte de temps. Les optimisations entre voodoo 2 et Radeon 9700 sont simplement antinomiques.
Tu ne peux tout simplement pas prévoir le même contenu pour les deux, ou alors tu sous exploitera ta Radeon 9700 ce que je n'appelerai pas de l'optimisation (mais du bridage).
john_john a écrit : Mais pour ça j'aimerais comprendre l'avantage structurel des glArrayElement et autres par rapport à glVertex. J'imagine que cet avantage doit se situer au delà de la simplification de l'appel de fonction (d'autant plus si on compare à glVertex3fv et son unique argument) |
L'interet des glArrayElement c'est de réduire le nombre d'appels à l'API pour décrire un simple polygone. De plus ces appels étant indexés, cela peut éviter de recalculer deux fois les transformations d'un vertex utilisé plusieurs fois dans le mesh d'un cube.
Si tu passes par glVertex, tu seras encore un peu plus limité par le nombre de polygones que ton CPU peut traiter. Le cout par polygone tracé est non acceptable pour un jeu moderne.
Si tu utilises les extensions modernes (ou passe à DirectX..), tu peux traiter le maximum de vertices sur ton CPU (ou les faire traiter indifféremment par le GPU).
LeGreg
Marsh Posté le 31-01-2004 à 18:29:25
jvois quon parle de direct3d dans le topic ...
c si bien que ca ? jen ai jamais fait c pour ca ....
par exemple pour linstant jai pas encore trouver 1 moyen de faire du pixel shader en opengl (ni un site avec un tuto dailleurs)
Marsh Posté le 31-01-2004 à 18:35:02
bah le mieux en OpenGl, c'est tu attrapes une carte OpenGl 1.4/1.5 (les rads 9500+ avec les derniers catalysts), et par exemple tu vas sur le site du gars qui avait fait l'offset bump mapping (j'ai plus le lien), et t'as plein de trucs avec le source qui va bien.
pour l'OpenGl/Direct3D, la seule gros différence, c'est que le Direct3D t'empêche pas mal de MAL faire, alors que l'OpenGl ayant évolué sur 15 ans, autorise les approches d'y il y a 15 ans... et permet donc de très mal faire.
Marsh Posté le 31-01-2004 à 18:40:58
oui mais ca a l'air beaucoup plus chaud opengl ca fait 2/3ans que jen fait jmaitrise bien maintenant le passage opengl direct3d se fera pas sans mal
Marsh Posté le 31-01-2004 à 19:12:59
Perso je prefere de loin direct3d, je trouve ca plus propre, plus coherent, et surtout unifié (les extensions proprio, je hais)
Marsh Posté le 31-01-2004 à 19:33:22
pour la programmation shaders en opengl
http://www.3dlabs.com/support/deve [...] V1.051.pdf
Marsh Posté le 01-02-2004 à 11:54:53
Citation : Ce que j'essayais de t'expliquer c'est qu'optimiser pour une voodoo 2 est de la perte de temps. Les optimisations entre voodoo 2 et Radeon 9700 sont simplement antinomiques. |
Et moi ce que je voulais dire c'est que mon programme n'a pas BESOIN d'etre optimisé lorsqu'il tourne sur radeon 9700. Ca marche déjà suffisamment bien. Par contre, sur voodoo2 c'est autre chose, et c'est justement là que je voulais travailler. Bien sûr les optimisations possibles sur radeon tirent massivement partie des technologies modernes et ne sont donc pas envisageables sur voodoo, mais comme je le dis, le moteur gagnerait beaucoup à être optimisé sur cette carte (considérant que j'aimerais qu'il tourne sur de nombreuses machines)
De plus, même si les optimisations sur voodoo sont d'une efficacité limitée par rapport aux optimisations possibles sur les cartes t&l, ces dernières en profiteront malgré tout. Et c'est ce que je cherche surtout actuellement. Bridage de radeon ? Oui et alors ? dirais-je. Ce que je veux c'est tourner sur des machines très différentes à des framerate au moins corrects.
Voilà pour mes motivations. Merci beaucoup pour vos explications et pour la description de glArrayElement je reviendrai polluer le forum plus tard au fil de mes progrès (si vous le permettez bien-sûr)
Marsh Posté le 01-02-2004 à 13:49:38
oki.
sinon, pour revenir aux optimisations générales:
1) tu changes tes propriétées de surface
2) tu traçes un maximum de triangles avec les mêmes propriétées e surface
tout changement de propriétée entraine entre un coût important ou faible....
pour les coordoonées de textures, les voodoo ne fontionnent pas en virgule flottante, et donc des coordoonées entières seront préférable.
Marsh Posté le 01-02-2004 à 19:35:04
Merci ! Je comprends mieux pourquoi ça marche pas super sur voodoo.
Marsh Posté le 02-02-2004 à 01:25:30
essayes, je suis pas sûr.
mais le mieux se serait de pomper la documentation du glide, tu auras beaucoup de détails sur les restrictions matérielle, et la manière idéale d'interfacer.
comme le driver MiniGl des Voodoo est un wrapper OpenGl->Glide, si tu utilises des formats ou une appoche non supportée par le Glide, tu auras un coût caché au niveau du Wrapper.
Marsh Posté le 02-02-2004 à 01:38:48
je crois que pour les voodoo, y'avait même des gars qui traçaient toutes les instances d'objets utilisant la même texture.
genre sur une carte actuelle tu vas faire (sans forcément te prendre la tête)
1) entitée 1 utlisant le modèle 12 ( on va dire un navion)
-> changement du repère du monde
-> set de la texture A (upload possible) et des autres propriéetes
-> traçage géométrie (on va dire le fuselage)
-> set texture B /propriétes (upload possible)
-> traçage géométrie (trains d'aterrissage
etc....
2) entitée 2 - modèle 33 (un autre avion)
-> chgment repère du monde
-> set texture C (upload ??)
-> traçages...
-> set texture D
....
3) entitée 3 - re modèle 12
-> chg rep
-> set texture A (upload ??)
...
...
4) entitée 4 - modèle 33
...
...
alors que ce qui pourrait être faisaible (ce qu'il me semble avoir vu faire)
1) set texture A (upload)
chg repère entitée 1
traçage géométrie fuselage
chg repère entitée 3
idem fuselage
2) set texture B
chg repère ent 1
traçage géom trains
chg repère ent 3
traçage géom trains....
3) set texture C
chg rep 2
traçage 2
chg rep 4
traçage 4
4) set texture D
chg rep 2
tr 2
chg rep 4
tr 4
...
....
...
en fait y'a pleins de possbilitées d'optimisation, avec des avantages et des inconvéniants, mais la règle d'or d'une part, c'est d'utiliser les appels à meilleur rendement
=> au revoir l'appel API par vertex
et ensuite de traçer le maximum de choses entre deux changement d'états (textures, prop matériaux)
ensuite pour la notion de traçage il encore des optimisations "locales au traçage": triangles séparés ou plusieurs strips ou encore un strip unique dégénéré, passage des vertexs de manière indexée ou pas (avec index: augmentation de bande-passante, mais autorise l'utilisation du cache Post-T&L pour les cartes T&L, et pareil évite au triangle setup de re-fetcher les vertexs lors de triangles adjacents)...
etc etc...
après tu peux avoir encore l'ordre de traçage, sans Z-buffer => obligatoirement du plus loin au plus près, avec Z-buffer => dans le désordre ou avec du plus près au plus loin ?
si du plus près au plus loin, plus de surfaces rejetées tôt dans le pipeline => meilleur fillrate moyen, mais surcharge CPU dû au coût du tri...
(j m'a gouré)
Marsh Posté le 02-02-2004 à 01:42:30
y'a aussi : desactivé toute ecriture dans le colorbuffer, rendre la scene (juste dans le zb quoi) et recommencer le rendu avec zwrite desactivé, ztest et colorbuffer activé
Marsh Posté le 02-02-2004 à 01:49:19
et si je devais utiliser une voodoo(2), vu qu'elle est pas T&L, le mieux serait de faire son propre code de projection en SSE en utilisant des vertexs déjà projetés (format j'entends)...
Marsh Posté le 02-02-2004 à 01:51:09
ou DX7 avec son VB:: optimize()
(smileu de daube)
note je sais pas ce qu'il vaut le support DX pour une voodoo ?
Marsh Posté le 02-02-2004 à 01:53:24
ché pas, mais je doutes que les coordonnées de texture en flottant lui soit amicales.... (voodoo 1/2 j'entends)
Marsh Posté le 02-02-2004 à 01:54:29
Chaipas, jamais developé en glide, DX a tjs été mon unique ami
par contre se faire chier a reecrire le code de transfo SSE... tout refaire en structure de tableau et tout, houla
spu de mon age
Marsh Posté le 02-02-2004 à 02:52:46
ché pas j'ai jamais pris le temps d'essayer, juste pour dire qu'avec une carte non T&L, autant se refaire son vertex shader en SSEuh......
sinon le Glide, c'était mon frangin qui avait imprimé la doc à l'armée (vengeance ), mais je crois qu'a l'époque j'hésitais à abandonner mon schmilblick en gouraud sous DOS
d'ailleurs c'était la doc du Glide 3.x, y'avait déjà des annotations pour le support futur du T&L...
Marsh Posté le 02-02-2004 à 08:11:42
John John,
ce n'est pas seulement un probleme technique: ta crédibilité est en jeu.
voodoo 2:
Radeon 9700 pro:
Imagine: tu vas optimiser tout ce que tu peux pour afficher la premiere image. Meme si tu réussis à la perfection, le résultat
sera au mieux anachronique.
Voila c'était ma contribution inutile au thread
LeGreg
Marsh Posté le 30-01-2004 à 22:11:38
Bonjour, petit nouvo sur le forum, je voudrais ouvrir un sujet de discussion sur l'optimisation des performances des applications opengl.
Je code actuellement en c++ un moteur qui commence à être pas mal au niveau de sa souplesse, de sa propreté et de sa flexibilité (il repose sur toutes une série de classes de descriptions)
J'ai encore beaucoup de choses à apprendre en opengl pourtant, et aujourd'hui je voudrais me pencher sur le probleme de glVertex. Je lis un peu partout que niveau performances, on fait beaucoup mieux avec
notamment glArrayElement.
Alors je me pose des questions sur le fonctionnement interne de ces deux primitives. Ce que je crois comprendre c'est:
- glVertex passe à la carte vidéo les coordonnées du vertex stockés dans la mémoire centrale de l'ordo
- glArrayElement indexe un vertex déjà stocké en mémoire vidéo et donc marche beaucoup plus vite
Merci aux intéressés, vos réponses me seront très utiles pour faire tourner mon moteur sur de vieux ordis (K6/2 350 et voodoo2 par exemple, ce qui n'est pas si vieux diront certains, et ils auront raison, mais il reste que cet ordi a du mal avec le bumpmapping)
Au prochain chapitre les performances de glBindTexture. (quelle mise en scène palpitante du suspens)