web-dev-qa-db-fra.com

Comment choisir entre GL_STREAM_DRAW vs GL_DYNAMIC_DRAW?

J'utilise OpenGL ES 2.0, mais je pense que cela concerne également les non-ES: comment savoir quel "usage" choisir lors de la création d'un VBO?

Ce VBO particulier sera utilisé 1 à 4 fois avant d'être complètement mis à jour, et je ne suis pas sûr de devoir choisir GL_STREAM_DRAW ou GL_DYNAMIC_DRAW.

26
lvella

Eh bien, selon l’API OpenGL , vous devez utiliser DYNAMIC_DRAW.

STREAM
Vous devez utiliser STREAM_DRAW lorsque le contenu du magasin de données sera modifié une fois et utilisé au plus quelques fois.

STATIQUE
Utilisez STATIC_DRAW lorsque le contenu du magasin de données sera modifié une fois et utilisé plusieurs fois.

DYNAMIQUE
Utilisez DYNAMIC_DRAW lorsque le contenu du magasin de données sera modifié à plusieurs reprises et utilisé plusieurs fois.

Assurez-vous de mettre à jour le VBO avec glBufferSubData ()

20
murk003

L'indicateur d'utilisation est un indice, pas une application. Ou en d'autres termes: les choses ne se cassent pas si vous utilisez un "mauvais" drapeau. Alors, je vous suggère d'essayer les 3: STATIC_DRAW, STREAM_DRAW et DYNAMIC_DRAW et de choisir celui qui vous donne les meilleures performances - et il est très probable qu'ils vont être à égalité.

11
datenwolf

Outre les réponses données jusqu'ici, et bien que cela n'ait rien à voir avec GLES, j'aimerais coller ce passage du numéro 2 de l'extension ARB_buffer_storage (introduit avec le bureau GL 4.4):

2) Les nouveaux indicateurs ne mappent pas directement sur le paramètre pour glBufferData et l’un ne peuvent pas être exprimés en termes de l’autre. Est-ce que cela importe?

usage est erroné dans la plupart des applications et il ne s'agit de toute façon que de conseils. Le les drapeaux sont des règles strictes qui doivent être suivies. Ils servent un but différent. L'idée ici est de permettre à l'implémentation de ne pas avoir à deviner l'application et à effectuer moins de suivi, et pour que l'application ait plus de contrôle. Nous définissons BufferData dans termes de BufferStorage avec les drapeaux autorisés les plus libéraux (essentiellement, tout est permis), mais transmettez toujours l'indication au mise en œuvre pour lui permettre de continuer à deviner le application.

Le problème de ces indicateurs a toujours été que chaque implémentation pouvait avoir des idées différentes sur la manière d'optimiser les différents chemins suggérés par l'indicateur d'utilisation, et chaque application semblait avoir des attentes différentes quant au fonctionnement de cette optimisation.

Le pilote GL de Nvidias dans un profil de débogage imprime certaines des décisions prises pour les objets de tampon, en particulier s’ils sont stockés dans le client RAM ou directement sur le GPU. En jouant avec cela, j'ai eu ce qui suit:

Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in Host memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in VIDEO memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped in Host memory.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) stored in SYSTEM HEAP memory has been updated.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use SYSTEM HEAP memory as the source for buffer object operations.
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).
Buffer detailed info: Buffer object 5 (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STATIC_DRAW) has been mapped WRITE_ONLY in SYSTEM HEAP memory (fast).

Ce que j'ai fait ici a été d'utiliser un PBO pour transférer les mises à jour de texture vers le GPU, avec une mise à jour par image via le mappage du tampon. Le choix naturel ici serait d'utiliser GL_STREAM_DRAW, mais j'ai spécifié GL_STATIC_DRAW. Ce que le pilote a fait, c’était au début de me fournir une mémoire tampon sauvegardée par VRAM et de mapper les E/S pour les deux premières mises à jour que j’ai effectuées. Mais ensuite, il a changé d'avis et utilise un tampon sauvegardé par le client - me donnant exactement le résultat que j'aurais obtenu si j'avais demandé GL_STREAM_DRAW en premier lieu. Ce que nous voyons ici est un exemple pour le second guessing dont parlait le texte cité ci-dessus.

Tout cela dépend fortement de la mise en œuvre. Et c’est aussi une des raisons pour lesquelles l’extension GL susmentionnée a été créée - ce qui donnera au programmeur beaucoup plus de contrôle sur ce genre de choses. Cependant, cette extension n'est, à ma connaissance, pas disponible sous OpenGL ES.

6
derhass

Pour IOS, les informations sur VBO sont ici sur le site du développeur Apple. Selon leurs documents GL_DYNAMIC_DRAW and GL_STREAM_DRAW are equivalent.

Mais je pense que votre solution est plus proche de GL_DYNAMIC_DRAW puisque GL_DYNAMIC_DRAW is for vertex buffers that are rendered many times, and whose contents change during the rendering loop.

1
mert