GL_STATIC_DRAW vs GL_DYNAMIC_DRAW vs GL_STREAM_DRAW: ¿importa?

11

En OpenGL, las funciones del objeto de almacenamiento intermedio ( glBufferData, glBufferSubDatay probablemente algunas otras) tienen un parámetro usage, descrito en la documentación como una pista del uso previsto, probablemente destinado a ayudar a la implementación a obtener un mejor rendimiento.

uso

Especifica el patrón de uso esperado del almacén de datos. La constante simbólica debe ser GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, o GL_DYNAMIC_COPY.
[...] el
uso es una pista para la implementación de GL sobre cómo se accederá al almacén de datos de un objeto de búfer. Esto permite que la implementación de GL tome decisiones más inteligentes que pueden afectar significativamente el rendimiento del objeto buffer. Sin embargo, no restringe el uso real del almacén de datos.

La wiki es igualmente vaga:

Estas son solo pistas, después de todo. Es perfectamente legal el código de OpenGL para modificar un búfer STATIC después de que se ha creado, o nunca modificar un búfer STREAM.
[...]
Estas son preguntas que solo pueden responderse con un perfil cuidadoso. E incluso entonces, la respuesta solo será precisa para esa versión de controlador en particular de ese proveedor de hardware en particular.

En resumen, ¿qué tan relevante es este parámetro, si es que lo es? ¿Los conductores realmente lo tienen en cuenta, y si lo hacen, en su experiencia, cuánto impacta en el rendimiento en la práctica? ¿Tienes datos para compartir?

He escrito una capa de abstracción de API de gráficos finos destinada a implementarse como cualquiera de las API existentes, y es tentador ignorar por completo este parámetro y ocultarlo de la abstracción expuesta.

Julien Guertault
fuente

Respuestas:

7

Esto variará entre las implementaciones, pero el controlador en el que trabajé sí las usó, principalmente para decidir el diseño de la memoria. Las optimizaciones habilitadas por estas sugerencias son mucho más pequeñas de lo que desearía, principalmente debido a la restricción de que puede usar cualquier sugerencia que dé. por ejemplo, la invalidación de caché sería mucho más barata si los buffers insinuados para acceso de lectura solo no pudieran escribirse, pero esta optimización es imposible.

Algunos juegos notables que se utilizan ampliamente para las comparaciones de referencia entre GPU no utilizan estas sugerencias correctamente, por lo que los proveedores de GPU tienen un incentivo para hacer todos los usos rápidamente, incluso si no coinciden con las sugerencias.

Dan Hulme
fuente
4

Funcionalmente son lo mismo.

El conductor podría usarlos para diferenciar cómo manejar el búfer detrás de escena. Donde, por ejemplo, static_draw se copiaría a vram lo antes posible y se dejaría allí, pero stream_read tendría una copia de la fecha de operación en RAM en todo momento.

Esta vaguedad es la razón por la que glBufferStorage se convirtió en una cosa. De esa manera, especifica lo que desea poder hacer con el búfer (si lo actualizará a través de BufferSubData, si leerá o escribirá en un mapa, qué tan coherente es el mapeo, si el mapeo puede persistir entre usos) e ir fuera de esos límites es un error.

monstruo de trinquete
fuente