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 glTexSubImage
pour 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 .