API graphique de bas niveau multiplateforme

11

Lors de la création d'une abstraction du système, il est préférable d'avoir la plate-forme API différente cachée par une interface commune au niveau le plus bas qui a du sens.

En tenant compte des différentes API graphiques natives modernes (sans pipeline de fonctions fixes): OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM

Si l'on devait créer une API graphique de bas niveau sans état pour s'asseoir au-dessus de toutes, quelle serait la meilleure façon d'aller pour la rendre aussi fine et aussi rapide que possible?

NocturnDragon
la source
L'obligation pour l'API d'être sans état est intéressante. OpenGL, par exemple, est dynamique, et je pense qu'une API sans état qui l'encapsule n'aurait de sens que si elle était de niveau beaucoup plus élevé, de sorte qu'il ne soit pas, par exemple, obligé de pousser et d'afficher les mêmes matrices pour chaque surface qu'il rend.
SpoonMeiser
Éviter les changements d'état inutiles pourrait toujours être implémenté à un niveau supérieur, comme en triant les appels de rendu en fonction de leur état avant de les soumettre au périphérique. Et en définissant l'état uniquement s'il est différent de l'état actuel.
NocturnDragon
Ce n'est cependant pas apatride. Peut-être que je me trompe, mais ce à quoi je pense quand je pense aux apatrides, c'est une API où chaque appel ne dépend pas du tout des appels précédents. Cela signifie que toute information qui serait normalement stockée dans un état quelque part doit être transmise à chaque appel nécessitant cette information. Pour OpenGL, par exemple, il s'agirait de matricies sur la pile, d'éclairage, de mise en mémoire tampon z et d'options de normalisation.
SpoonMeiser
Oui, pour chaque appel de dessin dont vous auriez besoin, les données de maillage, l'état de fusion, les textures à lier, les états d'échantillonnage, etc. Des optimisations pourraient être faites plus tard, sans changer l'API. Ou peut-être que je lis mal votre commentaire ..
NocturnDragon

Réponses:

6

Le niveau le plus bas qui a du sens de mon point de vue est quelque chose qui parle des ressources impliquées dans le rendu - vb / ib, surfaces de rendu, textures, shaders, blocs d'état, etc.

Le problème ici est que certains d'entre eux doivent être dans différents formats, selon l'API - c'est là que cela devient un peu délicat. Le moyen le plus simple consiste à pré-traiter les ressources statiques pour l'API respective. Pour les dynamiques, utilisez uniquement des shaders pour les générer - ce qui rend assez simple de rester dans des formats natifs.

Tout ce que vous faites ensuite au niveau supérieur est de configurer des pipelines avec des ressources attachées et de les remettre au GPU. Vous constaterez que tout ne peut pas être résumé de cette manière, surtout si vous profitez d'astuces spécifiques au matériel. Mais c'est un bon début.

(Sidenote: si vous traitez les astuces spécifiques à la plate-forme comme un type spécial de ressource, vous pouvez pousser ce concept tout à fait loin.)

Donc, d'une certaine manière, vous allez créer deux choses: un gestionnaire de ressources matérielles, plus une boîte à outils pour configurer un DAG de ces ressources.

Rachel Blum
la source
Je n'ai jamais pensé à traiter des choses spécifiques à une plateforme comme des ressources. Cela ressemble à une très bonne idée! Merci.
NocturnDragon
10

Étant donné le large éventail d'API que vous souhaitez couvrir, l'approche de wrapping typique est susceptible d'être inefficace et sujette à des difficultés dans la mise en correspondance des concepts d'API entre plusieurs autres API qui peuvent ou non prendre en charge des fonctions particulières à des degrés divers.

En conséquence, l'approche la plus judicieuse serait de créer une API centrée sur les fonctionnalités . Bien que cette approche empêche l'utilisateur de l'API d'utiliser toutes les fonctionnalités disponibles, elle simplifie considérablement la mise en œuvre de chaque backend et permet des optimisations spécifiques au backend qui ne seraient pas possibles autrement.

Il simplifie également considérablement la gestion des fonctionnalités non prises en charge pour l'utilisateur de l'API; ils n'ont plus à vérifier si la fonction X existe et à déterminer quelles fonctionnalités sont affectées, mais à la place ils n'ont qu'à interroger la fonctionnalité elle-même pour voir si elle est prise en charge avec la configuration actuelle. Même si vous prenez en charge des modes partiels ou limités pour les fonctionnalités, le contexte fourni le rend beaucoup plus facile à gérer.

En termes de création d'un moteur de rendu sans état (également appelé soumission ), une clé 64 bits est généralement utilisée pour emballer et soumettre des commandes pour le rendu. À partir de là, il y a une grande flexibilité en termes d'exécution des commandes et des informations à soumettre en fonction des fonctionnalités et capacités que vous souhaitez prendre en charge.

Jason Kozak
la source
C'est en fait une bonne idée. Et cela fait partie de la conception que j'essaie de créer, mais ce que j'avais à l'esprit était d'implémenter ces fonctionnalités en plus d'une API de bas niveau commune. Mais il se peut que pour certaines fonctionnalités, vous ayez encore besoin d'approfondir l'API native pour certains cas plus particuliers.
NocturnDragon
Une partie de l'idée consiste à éviter de créer une API commune de bas niveau et à devoir gérer le wrapping avec une approche au plus petit dénominateur commun. En augmentant le niveau d'abstraction d'un cran, vous restreignez légèrement l'ensemble des fonctionnalités, mais vous gagnez également la possibilité d'exploiter chaque plate-forme. Pour gérer le besoin occasionnel d'un accès plus profond, je préfère fournir un en-tête qui expose les en-têtes de la plate-forme et certains assistants internes; il peut se décomposer en version, mais il est là si vous en avez besoin.
Jason Kozak
1

Pour commencer, chaque API fait les choses différemment, il va donc sans dire que l'encapsulation de toutes les API ci-dessus serait difficile. Cela dit, il est parfois nécessaire de le faire: à un moment donné, un jeu doit simplement fonctionner sur plusieurs plates-formes, quelle que soit la difficulté.

Je pense que la meilleure façon de procéder est de proposer les fonctionnalités qui peuvent être implémentées sur toutes les API sous-jacentes et d'abstraire cela et seulement cela. Si vous développez un jeu multiplateforme, vous n'implémenteriez pas toutes les fonctionnalités obscures prises en charge par chaque API, vous implémenteriez uniquement ce dont vous avez besoin. Cela permet également de maintenir l'API petite et rapide.

Pour éviter d'encombrer l'implémentation de chaque API différente dans la sortie, la compilation doit être effectuée avec des fichiers d'en-tête neutres et des fichiers de code spécifiques à la plate-forme. Ensuite, le fichier de code spécifique à la plate-forme cible serait le seul à être compilé en maintenant l'API petite.

Sean James
la source
0

Il y a un article sur GPU Pro à ce sujet, par Emil Persson (Humus)

http://gpupro.blogspot.com/2009/12/making-it-large-beautiful-fast-and.html

Une interface multiplateforme pour le rendu. Les avantages d'en avoir un, et comment nous avons intégré DX10 dans une interface commune avec les consoles DX9 et maintenu de bonnes performances.

NocturnDragon
la source
-4

Vous voudrez peut-être consulter la bibliothèque SDL ou Allegro . Les deux sont des bibliothèques de jeux de bas niveau et hautement portables, qui ont un moyen de les brancher dans un contexte OpenGL afin que vous puissiez y rendre vos graphiques. SDL a la renommée d'être utilisé par le défunt Loki Games pour porter certains jeux populaires des années 2000 sur Linux, et Allegro a beaucoup de temps et dispose d'une grande communauté de développeurs de jeux amateurs.

chiguire
la source
4
Cela ne répond pas vraiment à la question, sans oublier qu'il est tout à fait possible d'envelopper OpenGL et DirectX (voir Ogre3D, Irrlicht, etc.).
Jason Kozak
Considérez les jeux auxquels vous avez joué. Combien d'entre eux ont des options pour utiliser DirectX ou OpenGL? C'est le nombre de wrappers créés pour que les deux bibliothèques puissent prendre en charge l'une ou l'autre. Vous avez une imagination limitée. :-P
Ricket
Je reconnais qu'il existe des jeux qui vous permettent de choisir si vous souhaitez rendre des graphiques avec OpenGL ou DirectX, mais la question concerne une API multiplateforme, donc je pense que la réponse est adéquate, je vais modifier le premier paragraphe, bien que.
chiguire
1
la question concerne une API de bas niveau sans état multiplateforme. SDL et Allegro n'y sont pour rien.
NocturnDragon
@NocturnDragon - le titre de la question est un peu trompeur. À première vue, je m'attendais à ce que la question porte sur les choix d'API disponibles, et je suppose que ce répondeur l'a fait également.
a_m0d