GL_STATIC_DRAW vs GL_DYNAMIC_DRAW vs GL_STREAM_DRAW: isso importa?

11

Em OpenGL as funções tampão de objectos ( glBufferData, glBufferSubData, e provavelmente alguns outros) têm um parâmetro usage, descrito pela documentação como uma sugestão da utilização pretendida, provavelmente destina-se a ajudar a execução de rendimento melhor desempenho.

uso

Especifica o padrão de uso esperado do armazenamento de dados. A constante simbólica deve 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, ou GL_DYNAMIC_COPY.
[...] o
uso é uma dica para a implementação do GL de como o armazenamento de dados de um objeto de buffer será acessado. Isso permite que a implementação do GL tome decisões mais inteligentes que possam afetar significativamente o desempenho do objeto de buffer. No entanto, não restringe o uso real do armazenamento de dados.

O wiki é igualmente vago:

Essas são apenas dicas, afinal. É um código OpenGL perfeitamente legal modificar um buffer STATIC depois que ele foi criado ou nunca modificar um buffer STREAM.
[...]
Essas são perguntas que só podem ser respondidas com um perfil cuidadoso. E mesmo assim, a resposta será precisa apenas para essa versão específica do driver daquele fornecedor de hardware específico.

Em suma, qual é a relevância desse parâmetro, se é que existe? Os motoristas realmente levam isso em consideração e, se o fazem, em sua experiência, quanto isso afeta o desempenho na prática? Você tem dados para compartilhar?

Eu escrevi uma camada fina de abstração de API de elementos gráficos que deve ser implementada como uma das APIs existentes, e é tentador ignorar completamente esse parâmetro e ocultá-lo da abstração exposta.

Julien Guertault
fonte

Respostas:

7

Isso varia entre as implementações, mas o driver em que trabalhei as utilizou, principalmente para decidir o layout da memória. As otimizações ativadas por essas dicas são muito menores do que você gostaria, principalmente por causa da restrição de que você pode usar qualquer dica que você der. por exemplo, tornaria a invalidação de cache muito mais barata se os buffers sugeridos apenas para acesso de leitura não pudessem ser gravados, mas essa otimização é impossível.

Alguns jogos notáveis ​​que são amplamente usados ​​para comparações de benchmarks entre GPUs não usam essas dicas corretamente, portanto, os fornecedores de GPU têm um incentivo para fazer todos os usos rapidamente, mesmo que não correspondam às dicas.

Dan Hulme
fonte
4

Funcionalmente, eles são os mesmos.

O motorista poderia usá-los para diferenciar como lidar com o buffer nos bastidores. Onde, por exemplo, static_draw seria copiado para o vram o mais rápido possível e deixado lá, mas stream_read teria uma cópia op-to-date na RAM o tempo todo.

Essa imprecisão é a razão pela qual glBufferStorage se tornou uma coisa. Dessa forma, você especifica o que deseja fazer com o buffer (se você o atualizará através do BufferSubData, se você lerá ou escreverá em um mapa, quão coerente é o mapeamento, se o mapeamento pode persistir entre os usos) e ir além desses limites é um erro.

catraca arrepiante
fonte