GL_STATIC_DRAW vs GL_DYNAMIC_DRAW vs GL_STREAM_DRAW: apakah itu penting?

11

Dalam OpenGL fungsi objek buffer ( glBufferData,, glBufferSubDatadan mungkin beberapa lainnya) memiliki parameter usage, yang dijelaskan oleh dokumentasi sebagai petunjuk penggunaan yang dimaksudkan, kemungkinan dimaksudkan untuk membantu implementasi menghasilkan kinerja yang lebih baik.

pemakaian

Menentukan pola penggunaan yang diharapkan dari penyimpanan data. Simbolis konstan harus GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, atau GL_DYNAMIC_COPY.
[...]
penggunaan adalah petunjuk untuk implementasi GL tentang bagaimana penyimpanan data objek buffer akan diakses. Ini memungkinkan implementasi GL untuk membuat keputusan yang lebih cerdas yang secara signifikan dapat memengaruhi kinerja objek buffer. Namun, itu tidak membatasi penggunaan sebenarnya dari penyimpanan data.

Wiki juga tidak jelas:

Bagaimanapun, ini hanyalah petunjuk. Ini adalah kode OpenGL yang sah untuk memodifikasi buffer STATIC setelah dibuat, atau untuk tidak pernah memodifikasi buffer STREAM.
[...]
Ini adalah pertanyaan yang hanya dapat dijawab dengan profil yang cermat. Dan bahkan kemudian, jawabannya hanya akan akurat untuk versi driver tertentu dari vendor perangkat keras tertentu.

Baik, seberapa relevan parameter ini, jika sama sekali? Apakah pengemudi benar-benar memperhitungkannya, dan jika mereka melakukannya, menurut pengalaman Anda, seberapa besar dampaknya terhadap kinerja dalam praktik? Apakah Anda memiliki data untuk dibagikan?

Saya telah menulis lapisan abstraksi API grafik tipis yang dimaksudkan untuk diimplementasikan sebagai salah satu dari API yang ada, dan tergoda untuk mengabaikan parameter ini sekaligus dan menyembunyikannya dari abstraksi terbuka.

Julien Guertault
sumber

Jawaban:

7

Ini akan bervariasi di antara implementasi, tetapi driver yang saya gunakan tidak menggunakannya, terutama untuk memutuskan tata letak memori. Optimalisasi yang diaktifkan oleh petunjuk ini jauh lebih kecil dari yang Anda inginkan, terutama karena pembatasan yang dapat Anda lakukan menggunakan petunjuk apa pun yang Anda berikan. misalnya itu akan membuat pembatalan cache jauh lebih murah jika buffer mengisyaratkan akses baca saja tidak dapat ditulis sama sekali, tetapi optimasi ini tidak mungkin.

Beberapa game terkenal yang banyak digunakan untuk perbandingan benchmark antara GPU tidak menggunakan petunjuk ini dengan benar, sehingga vendor GPU memiliki insentif untuk membuat semua penggunaan cepat bahkan jika mereka tidak cocok dengan petunjuk tersebut.

Dan Hulme
sumber
4

Secara fungsional mereka sama.

Pengemudi dapat menggunakannya untuk membedakan cara menangani buffer di belakang layar. Di mana misalnya static_draw akan disalin ke vram sesegera mungkin dan dibiarkan di sana tetapi stream_read akan memiliki salinan op to date dalam RAM setiap saat.

Ketidakjelasan ini adalah alasan mengapa glBufferStorage menjadi sesuatu. Dengan cara itu Anda menentukan apa yang ingin Anda lakukan dengan buffer (apakah Anda akan memperbaruinya melalui BufferSubData, apakah Anda akan membaca atau menulis melalui peta, seberapa pemetaan yang koheren, apakah pemetaan dapat bertahan di seluruh penggunaan) dan keluar dari batasan itu adalah kesalahan.

aneh ratchet
sumber