Quel est l'avantage du mécanisme d'accès direct à l'état d'OpenGL?

11

J'ai lu sur OpenGL 4.5 Direct State Access (DSA) sur opengl.org et je ne sais pas si je comprends bien.

Cela semble impliquer que l'ancienne méthode est moins efficace:

glBind(something)
glSetA(..)
glSetB(..)
glSetC(..)

que la nouvelle façon:

glSetA(something, ..)
glSetB(something, ..)
glSetC(something, ..)

À première vue, chacun glSetdoit maintenant inclure à l' glBind(something)intérieur de celui-ci et si OpenGL étant toujours une machine à états ne peut pas tirer parti des modifications en continu appliquées à un seul something.

Veuillez expliquer le raisonnement et les avantages du nouveau DSA.

Kromster
la source

Réponses:

21

D'après son apparence, chaque glSet doit inclure glBind (quelque chose) à l'intérieur

Pas exactement. C'est l'inverse, comme décrit plusieurs paragraphes ci-dessous.

Même si c'était vrai, rappelez-vous que les commandes GL de l'application cliente au serveur GL (aka pilote) ont beaucoup de frais de répartition par rapport à un appel de fonction normal. Même si nous supposons que les fonctions DSA ne sont que des wrappers autour des fonctions existantes, ce sont des wrappers qui vivent à l'intérieur du serveur GL et peuvent donc avoir (un peu) moins de surcharge.

si OpenGL étant toujours une machine à états ne peut pas profiter des modifications en continu appliquées à un seul élément.

Les GPU ne sont pas des machines d'état. L'interface de machine d'état GL est une émulation qui encapsule les pilotes internes de type DSA, et non l'inverse.

La suppression d'une couche de wrapping - une couche qui nécessite un nombre excessif d'appels sur le serveur GL - est clairement une victoire, même petite.

L'approche de la machine d'état n'a pas non plus beaucoup de sens lorsqu'il s'agit de plusieurs threads; GL est toujours terrible dans ce cas d'utilisation, mais les pilotes utilisent souvent des threads en arrière-plan, et une machine d'état nécessite beaucoup de synchronisation de threads ou des algorithmes / constructions parallèles vraiment fantaisistes pour que les choses fonctionnent de manière fiable.

L'extension DSA continue d'exprimer son fonctionnement en termes de changements d'état car il s'agit, après tout, d'une extension à un document basé sur l'état existant et non d'une API entièrement nouvelle, donc elle devait être prête à se connecter à la spécification GL existante langue et terminologie du document. Même si ce langage existant est assez terriblement adapté à son travail en tant qu'API matérielle graphique moderne.

Veuillez expliquer le raisonnement et les avantages du nouveau DSA.

Le plus grand raisonnement est que l'ancienne méthode était pénible. Cela a rendu très difficile la composition de bibliothèques qui pouvaient chacune modifier ou s'appuyer sur l'état GL. Il a été difficile d'encapsuler efficacement l'API GL dans un style orienté objet ou fonctionnel en raison de ses racines profondes de gestion des états procéduraux, ce qui a rendu difficile l'encapsulation de l'API dans divers langages non-C et a également rendu difficile la fourniture d'encapsuleurs de périphériques graphiques efficaces. cet OpenGL abstrait de Direct3D.

La seconde était la surcharge de l'API de la machine à états procédurale, comme décrit précédemment.

Troisièmement, les fonctions DSA ont modifié la sémantique, le cas échéant, par rapport aux anciennes API, ce qui a permis d'améliorer l'efficacité. Les choses qui étaient auparavant mutables sont devenues immuables, par exemple, ce qui supprime beaucoup de code de comptabilité du serveur GL. Les appels de l'application peuvent être envoyés au matériel ou validés plus tôt (ou de façon plus parallèle) lorsque le serveur GL n'a pas à gérer des objets mutables.

-

Une justification et une explication supplémentaires sont fournies dans la spécification d'extension EXT_direct_state_access .

-

Les modifications matérielles pertinentes pour la conception de l'API sont assez nombreuses.

N'oubliez pas qu'OpenGL remonte à 1991. Le matériel cible n'était pas des cartes graphiques grand public (celles-ci n'existaient pas) mais de grandes stations de travail CAO et similaires. Le matériel de cette époque avait des enveloppes de performances très différentes de celles d'aujourd'hui; le multi-threading était plus rare, les bus mémoire et les CPU avaient moins d'écart de vitesse, et le GPU ne faisait guère plus que le rendu triangulaire à fonction fixe.

De plus en plus de fonctions fixes ont été ajoutées. Divers modèles d'éclairage, modes de texture, etc. ont tous été ajoutés, chacun ayant besoin de son propre état. L'approche basée sur un état simple fonctionnait lorsque vous aviez une poignée d'états. À mesure que de plus en plus d'états ont été ajoutés, l'API a commencé à exploser. L'API est devenue plus maladroite mais ne s'est pas trop éloignée des modes matériels, car ils étaient en effet basés sur de nombreux commutateurs d'état.

Puis vint le matériel programmable. Le matériel est devenu de plus en plus programmable, au point où maintenant, le matériel prend en charge un petit état, certains programmes fournis par l'utilisateur et beaucoup de tampons. Tout cet état de l'ère précédente devait être émulé, tout comme toutes les fonctionnalités à fonction fixe de cette ère étaient émulées par les pilotes.

Le matériel a également changé pour être de plus en plus parallèle. Cela a nécessité d'autres remaniements matériels qui ont rendu les changements d'état graphique très coûteux. Le matériel fonctionne en gros blocs d'état immuable. En raison de ces modifications, le pilote ne pouvait pas simplement appliquer chaque petite partie de l'état défini par l'utilisateur immédiatement, mais devait regrouper automatiquement les modifications et les appliquer implicitement en cas de besoin.

Le matériel moderne fonctionne encore plus loin du modèle OpenGL classique. DSA est un petit changement qui était nécessaire il y a plus de 10 ans (il avait été initialement promis dans le cadre d'OpenGL 3.0), similaire à ce que D3D10 a fait. La plupart des modifications matérielles ci-dessus nécessitent bien plus qu'un simple DSA pour garder OpenGL pertinent, c'est pourquoi de plus grandes extensions qui changent radicalement le modèle OpenGL sont disponibles . Ensuite, il y a la toute nouvelle API GLnext plus D3D12, Mantle, Metal, etc. pas une seule qui conserve l'abstraction de la machine d'état obsolète.

Sean Middleditch
la source
Merci d'avoir répondu. Il semble donc qu'avant un certain point, la machine à états (non DSA) était une victoire, mais à un moment donné, quelque chose a changé et maintenant le DSA est avantageux. Pouvez-vous nous éclairer sur ce qui a changé?
Kromster
@KromStern: a fait de mon mieux. Si vous avez besoin de plus de détails, quelqu'un de mieux informé que moi va devoir vous le fournir.
Sean Middleditch
@KromStern J'ai vu (à partir de mes recherches limitées dans l'histoire) openGL se déplacer vers de moins en moins d'appels CPU côté par image; afficher les listes (pour ce qu'elles valaient), glDrawArrays (dessiner en un seul appel), VBO (télécharger vers le GPU une fois), VAOs (lier les tampons aux attributs une fois), objet tampon uniforme (définir les uniformes en une seule fois). Il y a plus que je manque, j'en suis sûr.
ratchet freak
@ratchetfreak: assez drôle, nous allons dans l'autre sens maintenant. Les API / extensions modernes se concentrent sur l'augmentation de nos appels de tirage par trame, principalement en supprimant tout cet état qui doit être défini / distribué par appel de tirage et en faisant les appels de tirage un peu plus que «insérer la commande de tirage dans la file d'attente de commandes» contre un grand ensemble d'état statique et de ressources sans liens. Oooh, sans reliure, j'ai oublié de mentionner même cette partie dans ma réponse.
Sean Middleditch
@SeanMiddleditch J'aurais dû définir des appels par image.
ratchet freak
1

L'aperçu le justifie par:

L'intention de cette extension est de la rendre plus efficace pour les bibliothèques afin d'éviter de perturber le sélecteur et l'état verrouillé. L'extension permet également une utilisation plus efficace des commandes en éliminant le besoin de commandes de mise à jour du sélecteur.

Je pense que "plus efficace" se réfère ici à la fois à la réduction des frais de tenue de livres pour les auteurs de bibliothèque et à des performances plus élevées. Avec l'API actuelle, pour être "bien comporté", vous devez interroger l'état, le ranger, changer l'état pour faire ce dont vous avez besoin, puis restaurer l'état d'origine.

Comme

oldState = glGet()
glBind()
glDoThings...
glSet(oldState)  // restore, in case anyone needs it just as they left it

Vraisemblablement, le matériel plus ancien pourrait être rendu plus performant avec l'API explicite à changement d'état; c'est un rituel assez étrange sinon. Cette extension implique (et regardez simplement la liste des auteurs!) Qu'éviter cette danse de récupération, de définition et de restauration est désormais plus un gain de performances sur le matériel actuel, même avec le paramètre supplémentaire à chaque appel.

david van brink
la source
"besoin d'interroger / cacher / modifier / restaurer" - comment est-ce mieux avec DSA?
Kromster
..ajout d'un pseudo code à afficher. Avec DSA, rien de tout cela n'est nécessaire. Vraisemblablement, le matériel actuel n'a pas vraiment besoin d'un état de "liaison", il peut simplement accéder à tout cela selon les besoins.
david van brink
La chaîne get/bind/do/setest rarement utilisée, car «Get» est très lent. Habituellement, les applications doivent conserver une réplique des variables de toute façon, donc cela se réduit à juste bind/do. Je vois le point cependant.
Kromster
2
@krom get from driver state peut être rapide, une partie de l'état gettable n'a aucune raison d'être sur le GPU, il peut donc être obtenu à partir de la RAM qui est rapide.
ratchet freak