La modification d'une texture (peinture dessus) est-elle considérée comme un «changement d'état»?

11

La convention dans les graphiques est qu'il est préférable d'effectuer moins de changements d'état que d'effectuer plus de changements d'état (commutation des shaders, liaison des tampons, liaison des textures, etc.). Pour les textures, il est plus rapide de rendre de nombreux polygones à l'aide d'un seul atlas (pour le rendu des sprites / du texte) que de lier individuellement une nouvelle texture pour chaque polygone.

Est-ce vrai si je peins continuellement sur une texture via glTexSubImage2D? J'ai un flux de données entrant (sur un réseau) qui subit un traitement et est ensuite peint sur une texture une ligne à la fois. Les données sont présentées visuellement dans un défilement sans fin.

Serais-je mieux de peindre sur une texture rendue sur un grand rectangle (faire défiler les données peintes en vue)? L'idée ici est que j'aurais une (ou deux) textures liées à un moment donné pendant que je continue à peindre dessus.

Ou devrais-je peindre beaucoup de petits rectangles (révéler le rectangle uniquement lorsque la peinture est terminée)? Je suppose que je lierais une texture par rectangle.

TheBuzzSaw
la source

Réponses:

11

La mise à jour d'une zone de mémoire dans le périphérique graphique (une texture, un tampon, etc.) n'est pas tout à fait la même chose que de changer un état de rendu.

Ce qui rend un changement d'état de rendu coûteux, c'est la quantité de travail que le pilote doit faire pour valider le ou les nouveaux états et réorganiser le pipeline. Cela entraînera très probablement également une synchronisation entre le processeur et le périphérique graphique. Cependant, la quantité de données transférées entre les appareils doit être faible pour un changement d'état (probablement juste quelques commandes).

En revanche, pour une mise à jour de texture / tampon, le coût principal réside dans le transfert de données lui-même. En théorie, à moins que vous ne lisiez les données de texture au processeur après la mise à jour, il ne devrait pas y avoir de synchronisation ou de blocage de pipeline. Cependant, un autre aspect doit être pris en compte: les frais généraux de l'API. Même si la quantité de données que vous envoyez au périphérique graphique est faible, si vous le faites assez souvent, le coût de la communication avec le pilote / périphérique deviendra éventuellement plus élevé que le coût du transfert de données. C'est une autre raison pour laquelle le traitement par lots est si important lors de l'optimisation d'un moteur de rendu.

Donc, dans votre cas, la meilleure approche, me semble-t-il, serait de conserver une copie de la mémoire système de la texture que vous mettez à jour chaque fois que de nouvelles données arrivent. Définissez un indicateur sale et consolidez autant de mises à jour que possible en une seule glTexSubImagepour toute la texture (ou une grande partie séquentielle). Vous pouvez également jouer avec Pixel Buffer Objects et essayer de faire un transfert de données asynchrone pour réduire autant que possible les blocages de pipeline. Si vous pouvez implémenter une sorte de double tampon, vous pouvez écrire sur une copie de la texture pendant que l'autre est rendue avec. Ce tutorielexplore ce scénario. C'est mon approche intuitive, j'essaierais de réduire le nombre d'appels d'API et de "batch" les mises à jour de texture. Cela étant dit, cela est très spéculatif, et vous devrez le profiler et le comparer à d'autres approches, comme faire plusieurs petites mises à jour, pour savoir avec certitude quelle est la plus performante dans votre cas d'utilisation.

En guise de remarque, cette présentation de NVidia est également pertinente et fournit beaucoup de bonnes idées: Approche de Zero Driver Overhead dans OpenGL .

glampert
la source
5
Je ne sais pas avec certitude, mais je soupçonnerais certainement que glTexSubImage sur une texture qui a été rendue dans la dernière ou les deux dernières images bloquera le pipeline, car les pilotes PC essaient souvent de mettre en mémoire tampon une ou deux images, et ne sont pas susceptibles vouloir faire des copies de textures entières à cause d'une petite mise à jour. Je m'attends donc à ce que la double ou triple mise en mémoire tampon des textures (ou des objets de tampon de pixels) soit nécessaire pour des performances maximales.
John Calsbeek