M1’de Uygunluk Sertifikalı OpenGL 4.6 Desteği
(rosenzweig.io)- M1, yıllarca OpenGL 4.1’de takılı kalmıştı; ancak Fedora Asahi Remix’in en yeni M1/M2 sürücüleri OpenGL 4.6 ve OpenGL ES 3.2 için tam destek sunuyor
- Asahi’nin açık kaynak Linux sürücüsü, üreticinin uyumsuz 4.1 sürücüsünün aksine Khronos listesinde yer alan uygunluk sertifikalı bir sürücü; Blender gibi modern OpenGL iş yükleriyle uyumluluğu genişletiyor
- OpenGL 4.6; robustness, SPIR-V, clip control, cull distance, compute shaders ve geliştirilmiş transform feedback gerektiriyor, ancak M1 donanımı modern grafik standartlarına doğrudan uymuyor
- Donanımda bulunmayan özellikler sürücü ve derleyici teknikleriyle tamamlanıyor: geometry shaders, tessellation ve transform feedback compute shaders ile; cull distance ve clip control ise shader dönüşümleriyle işleniyor
- 100.000’den fazla uygunluk testini geçmek için buffer ve image robustness yazılımda uygulanıyor; clamp, preamble optimizasyonu ve mipmap geçici çözümleriyle ek maliyet azaltılıyor
Fedora Asahi Remix’te OpenGL 4.6/ES 3.2 kullanılabilir
- M1 şimdiye kadar yalnızca OpenGL 4.1’i destekliyordu; artık OpenGL 4.6 ve OpenGL ES 3.2 destekleniyor
- En yeni M1/M2 serisi sürücüler Fedora Asahi Remix kurulumu ile kullanılabilir
- Zaten kurulu olan kullanıcılar aşağıdaki komutla güncelleyebilir
dnf upgrade --refresh
- Asahi’nin açık kaynak Mesa sürücüsü, üreticinin uyumsuz 4.1 sürücüsünün aksine en yeni OpenGL sürümleri için uygunluğa (conformance) sahip
- Uygun 4.6/3.2 sürücüler, doğruluğu garanti etmek için 100.000’den fazla testi geçmek zorunda
- Khronos’un resmi listesinde Asahi’nin OpenGL 4.6 ve OpenGL ES 3.2 kayıtları yer alıyor
- Altı ay önce OpenGL ES 3.1 sürücüsüyle M1 için standart grafik API’lerine yönelik ilk uygun sürücünün çıkmasının ardından, bu kez OpenGL 4.6 da tamamlandı
- Vulkan desteği de geliştirme aşamasında
OpenGL 4.1 engelini aşmak için özelliklerin uygulanması
- OpenGL 4.6, 4.1’e kıyasla çeşitli zorunlu özellikler ekliyor
- Robustness
- SPIR-V
- Clip control
- Cull distance
- Compute shaders
- Yükseltilmiş transform feedback
- M1, OpenGL ES 3.1’den daha yeni grafik standartlarına pek iyi uymuyor
- Vulkan bazı özellikleri isteğe bağlı hale getiriyor; ancak DirectX ve OpenGL’i bunun üzerine katmanlamak için eksik özellikler gerekiyor
- M1’in mevcut çözümleri OpenGL 4.1 özellik setinin ötesine geçemiyordu
- Donanım desteği olmayan yeni özellikler sürücü teknikleriyle uygulanıyor
- Geometry shaders, tessellation ve transform feedback compute shaders ile işleniyor
- Cull distance, dönüştürülmüş interpolasyon değerleriyle ele alınıyor
- Clip control, vertex shader epilogue ile uygulanıyor
Buffer robustness ve M1’in yazılım düzeltmesi
- GPU’lar geleneksel olarak güvenlikten çok performansa öncelik verdiği için, shader’ın buffer sınırının dışını okuduğu hatalı kodlarda tanımsız davranış ortaya çıkabilir
- Web tarayıcıları gibi güvenilmeyen shader’larla çalışan uygulamalarda bu tür bir ödünleşim istenmez
- Grafik API’sinin kendisi bir güvenlik sınırı olmadığından bir miktar sanitization gerekir
- API’deki tanımsız davranışı azaltmak, derinlemesine savunmaya yardımcı olur
- Robustness etkinleştirildiğinde uygulama, bir miktar performanstan vazgeçerek sınır dışı erişimler için tanımlı davranışı seçebilir
- API’ye göre sınır dışı buffer load sonuçları farklıdır
- Direct3D ve Vulkan
robustBufferAccess2: 0 döndürür - OpenGL ve Vulkan
robustBufferAccess: 0 veya buffer içindeki bazı verileri döndürür - OpenGL ES: rastgele değer olabilir, ancak çökmez
- Direct3D ve Vulkan
- OpenGL gereksinimi, sınır dışı erişimde 0 veya buffer içindeki veriyi döndürmek olduğundan, son geçerli indeks ile erişim indeksinin unsigned minimum değeri hesaplanarak güvenli bir indeksle load yapılabilir
- robustness olmadan uniform buffer load:
load.i32 result, buffer, index - robustness uygulandıktan sonra:
umin idx, index, lastardındanload.i32 result, buffer, idx
- robustness olmadan uniform buffer load:
- M1’in preamble yapısı, tüm thread’lerde aynı değeri tekrar tekrar hesaplamak yerine bir kez hesaplayıp yeniden kullanır
- uniform buffer boyutu sabit olduğundan ek robustness aritmetiği de preamble’a taşınabilir
- robust storage buffer’da load/store işlemlerinin kendisi taşınamasa bile clamp hesaplaması preamble’a taşınabilir
Vertex buffer robustness uygulaması
- Grafik API’sinde uygulama, vertex buffer’ın GPU base address’ini ve attribute layout’unu ayarlar
- Her attribute bir offset ve format içerir
- Buffer, vertex başına byte sayısını gösteren stride değerine sahiptir
- Vertex shader, attribute’ları vertex’e göre örtük olarak indeksleyerek okur
- Bazı donanımlar robust vertex fetch’i native olarak uygular veya bounds-checked buffer ile software fetch’i hızlandırır; ancak M1’de ikisi de yoktur
- M1 GPU bellek load işlemleri 64 bit base address ve element birimli offset alır; ayrıca
imadinteger multiply-add komutunu da sunar- 32 bit attribute load,
imad idx, stride/4, vertex, offset/4veload.i32 result, base, idxolmak üzere iki komutla uygulanabilir - Yoğun biçimde yerleştirilmiş dört 32 bit değerden oluşan vector attribute,
load.v4i32 result, base, vertex << 2tek komutuyla yüklenebilir
- 32 bit attribute load,
- Robustness için clamp gerekir; ancak vertex buffer boyutu byte cinsindendir ve optimize edilmiş load, vertex birimli index kullanır
- Tek bir buffer içindeki birden çok attribute ve offset, attribute başına ayrı base address gibi yeniden yorumlanarak sorun çözülür
- Offset’i shader’da eklemek yerine attribute başına base aktarılır
- Byte birimli buffer boyutu, her attribute için vertex birimli boyuta dönüştürülebilir
- Offset yerine vertex index clamp edilir
- Sürücü, her attribute formatının boyutunu kullanarak son geçerli vertex index’ini önceden hesaplar ve shader’a aktarır
- Buffer herhangi bir şey yükleyemeyecek kadar küçükse clamp sorunu çözmez; bu durumda ilgili attribute’un buffer’ı küçük bir zero buffer ile değiştirilir
- Attribute başına base address kullanıldığı için bu karar da attribute bazında verilebilir
- Sonuç olarak az miktarda sürücü hesabı ve tek bir
uminmaliyetiyle robust vertex buffer uygulanır
Image robustness ve mipmap geçici çözümü
- Buffer robustness dışında image robustness da gerekir; sınır dışı image load 0 döndürmelidir
- Mipmapped image birden çok level of detail içerir
- Base level, orijinal görüntüdür
- Sonraki her level, önceki level’in küçültülmüş görüntüsüdür
- Render sırasında donanım, verimliliği ve görsel kaliteyi artırmak için ekran boyutuna yakın level’i seçer
- Spesifikasyon, robustness kapsamında image load’un aşağıdaki durumlarda 0 döndürmesini ister
- X veya Y koordinatı sınır dışındaysa
- Level sınır dışındaysa
- M1 GPU’nun image load davranışı gereksinimlerden farklıdır
- X veya Y koordinatı sınır dışındaysa 0 döndürür
- Level sınır dışındaysa son level’in değerini döndürür
- Üretici donanım dokümantasyonunu yayımlamadığından bu davranışın kasıtlı mı yoksa donanım hatası mı olduğu bilinemez; uygunluğu geçmek için bir geçici çözüm gerekir
- Basit geçici çözüm, level geçerliyse load yapıp değilse 0 döndüren branch yaklaşımıdır; ancak branch verimsizdir
- Daha iyi yöntem, sınır dışı level’de bile load’un çökmediği gerçeğinden yararlanarak önce load yapmak ve compare-select ile 0’ı seçmektir
- Ancak M1 GPU’nun komut seti scalar’dır ve image load red/green/blue/alpha olmak üzere 4 component’li bir vector döndürür
- Her component için
uleselgerektiğinden assembly büyür
- Nihai geçici çözüm, X veya Y sınır dışındaysa donanımın 0 döndürmesi gerçeğinden yararlanır
- Maksimum image genişliği 16384 px olduğundan X’i 20000 gibi bir değere değiştirmek sınır dışına çıkarır
- Level geçerliyse orijinal X kullanılır; geçerli değilse X 20000’e değiştirilerek image load’un 0 döndürmesi sağlanır
- Bu yöntem vector’ün tamamını seçmek yerine yalnızca tek bir scalar’ı değiştirdiği için kompakt assembly’ye derlenir
- Sabit değer uniform register’a önceden alınırsa geçici çözümün maliyeti tek komut olur
- Bu yöntemle conformance geçilir
1 yorum
Hacker News yorumları
Alyssa Rosenzweig topluluğa katkı yapmayı sürdüren büyük bir nimet gibi görünüyor
Her blog yazısında modern grafik donanımının iç yapısı hakkında mutlaka daha önce bilmediğim bir şey öğreniyorum
Bu çalışma, her seferinde sözden çok becerinin kazandığını gösteriyor
Sadece blogu okumak bile kafayı alevlendirecek kadar içine girilecek konu sunuyor; üstelik sonuç son cümlede değil ikinci cümlede olsa da, insan yine bit manipülasyonlarını tek tek takip ederek tavşan deliğine giriyor
Paragraf başına içgörü sayısı diye bir benchmark olsa Alyssa hepsinde birinci olurdu gibi geliyor
Bir gün Apple OpenGL 3.3 core desteğini kaldırırsa sonunda herkes de peşinden kaldırabilir
Genel olarak OpenGL'in Vulkan'dan daha kolay kullanıldığı söyleniyor; aşırı karmaşık API'ler, deneyimi az geliştiricilerin GPU'dan yararlanmasını zorlaştırıp giriş engeli oluşturarak bağımsız oyun geliştiricilerini dışarı itebilir
Bugünlerde herkes Unity ve Unreal kullanıyor; bu yüzden sıfırdan başlamak ya da başka bir motor kullanmak tuhaf karşılanıyor. Unity daha da kilitlemeye çalıştıktan sonra oyun geliştirmenin bu alanda uyanışını izlemek ilginç ama bir yandan da sinir bozucu
Oyun geliştirmede açık kaynak hep dardı; Godot var ama Unity ve Unreal'a ciddi biçimde karşı koyması zor görünüyor
Godot yeterince iyi olsa bile, bağımsız geliştiriciler Unity ve Unreal'a daha alışık olduğu için orada kalmaları muhtemel
Oyun geliştirmede açık kaynağın durumu bazen umutsuz hissettiriyor ve yeni nesil grafik API'lerinin gelişi işleri kolaylaştırmıyor
OpenGL üçgen render etme örneği yaklaşık 200 satırken, Vulkan üçgen render etme örneği yaklaşık 1000 satır
Vulkan çok esnek tasarlanmış ama buna karşılık fazla kolaylık sağlamıyor
Her iki durumda da OpenGL, sürücünün doğrudan API'si olarak açığa çıkarılmak için fazla yüksek seviyeliydi; temel katmanda Vulkan gibi düşük seviyeli bir API bulundurup onun üstüne OpenGL benzeri bir şey koymak, GPU donanımının çalışma biçimiyle daha iyi örtüşüyor
Ayrıca herkes Unity ve Unreal da kullanmıyor
The Game Awards 2023'te yılın oyunu aday gösterilen 6 oyunun tamamı kendi motorlarıyla yapıldı; bağımsız tarafta da Hades gibi kendi motorunu kullanan geliştiriciler hâlâ var
Yine de çoğunluk için hazır motor kullanmak mantıklı
İhtiyaç duyulan özelliklerin hepsini karşılıyor ve durum tabanlı render pipeline'ını kabul edebiliyorsanız, yeni projelerde kullanmak da gayet iyi bir tercih
Hâlâ çalışıyor ve bugünlerde Metal üzerindeki bir katman aracılığıyla yürütülüyor ama macOS ya da iOS için GL kodu derlerseniz sürekli kullanımdan kaldırma uyarısı alıyorsunuz
Bunu bir
defineile kapatabilirsinizOpenGL'in sorunu, GPU'nun çalışma biçiminden fazla uzak olması; bu yüzden yüksek performans elde etmek zor
Bu çalışmanın ne kadarının M1 GPU koduna sıkı sıkıya bağlı olduğunu ve ne kadar özellik-üstüne-özellik uygulamasının başka yerlerde de yeniden kullanılabileceğini merak ediyorum
Zink'in daha ilkel Vulkan üzerinde karmaşık OpenGL özelliklerini çalıştırma biçimine çok benziyor, ama M1 için henüz hedef alınabilecek bir Vulkan backend yok
Sonuçta mesele iş yükü ve farklı donanımlarda yeniden kullanılabilir
Eski olduğu için iyi anlaşılmış ama modern iş yüklerinde tek başına kullanılması zor olan donanımlar için de faydalı olabilir
Bunun yarattığı performans etkisinin, özellikle macOS'ta, Metal'i doğrudan kullanmaya kıyasla ne düzeyde olduğunu gerçekten merak ediyorum
Cevap belli ki “duruma göre değişir” olacak ama yine de merak ediyorum
Yazının içinde yanıtı olabilir ama çoğunu anlayamadım
“Donanım desteği” de çoğu zaman GPU mikrokodu ile uygulanıyor ve çoğu durumda aynı silikon üzerinden geçiyor
Her özellik performans darboğazı olabilir; gerçekten denemeden önce nerede tıkanacağını bilmek zor
Apple GPU'larının geometry shader'ı yerel olarak desteklemediği doğru, ama geometry shader zaten iyi tasarlanmış bir özellik değil ve GPU donanımına da pek uymuyor
Gerçekten destekleyen donanımlarda bile yavaş olduğu biliniyor; Nvidia'nın mesh shading tasarlamasının bir nedeni var
Transform feedback de sık anılıyor ama Apple GPU'ları herhangi bir shader aşamasında bellekte rastgele konumlara yazabildiği için transform feedback fiilen gereksiz
Asıl mesele, Apple'ın sade bir compute mimarisi uygularken eski yükleri ve iyi çalışmadığı bilinen birçok özelliği kesip atmış olması
“M1, OpenGL 4.1'e sıkıştı” ifadesi pek uygun görünmüyor
Apple uzun zaman önce OpenGL'i takip etmeyi bıraktığı için 4.1 sonrasında hangi özelliklerden söz edildiğini bilmiyorum; ama OpenGL'de yapılıp Metal'de yapılamayan bir şey varsa buna çok şaşırırım
Tersi yönde ise, Metal'de mümkün olup OpenGL'de tamamen imkânsız olan çok şey var; buna örnek olarak Metal shading language'deki tam pointer desteği verilebilir
Bu, M1’in Fedora sürümü için
macOS’ta da mümkün hale gelirse şaşırtıcı olurdu; ama bunu yapmak için ne gerektiğini merak ediyorum
M1 GPU için ilk Mesa sürücüsü de macOS’un AGX sürücüsüne IOKit ile komut arabellekleri göndererek bootstrap edilmişti
https://rosenzweig.io/blog/asahi-gpu-part-2.html
https://github.com/AsahiLinux/gpu/blob/main/demo/iokit.c
Bu yüzden GPU’nun surface’ini macOS ekranında birleştirilebilecek bir hedefe aktarmak için Mesa tarafında biraz daha yapıştırıcı kod gerekiyor
Düzgün bir Vulkan ya da OpenGL uygulaması yapmak için GPU işlemlerinden sorumlu çekirdek tarafında bir eş gerektiğini anlıyorum
Muhtemelen bu yüzden macOS için yerel Vulkan gerçekleştirmeye çalışan kimse yok
Ama Apple sürücülerinin üstünde mümkünse, ondan emin değilim
Ama optimal olmayan bir legacy API için bu kadar çok kaynak harcamak için bir neden var mı, emin değilim
Sınır dışı erişimi trap’ten rastgele veri döndürmeye çevirmeye sağlamlık demeleri epey komik
Grafik programlama gerçekten tuhaf
GPU sürücülerinin asıl işi bozuk uygulamaları çalıştırmak ya da onları daha hızlı çalıştırmak
Varsayılanları katılaştırmak, kırık kod yayınlayan video oyun sektöründeki yapısal sorunu çözmez; sadece kullanıcıları uzaklaştırır
Dallanmanın genelde çok pahalı olduğu donanımlarda, sistemin sınır durumlarını en verimli şekilde sessizce ele almasını söyleyen bir bayrak kullanışlı görünüyor
Programcının bu tür sınır durumlarının nihai render karesine neredeyse hiç etkisi olmadığından makul biçimde emin olabileceği birçok geçerli kullanım alanı da vardır muhtemelen
Bu da GPU’ların genel olarak trap’lerden pek hoşlanmamasıyla uyumlu
Carmack da megatexture tasarlarken üreticilere sanal bellek fikrini kabul ettirmenin acı verici olduğunu söylemişti
“Performans güvenliğin önündedir” kültürünün egemen olduğu alanlarda başka programlama dillerinden söz etmek, duvara konuşmaya benziyor
Kesinlikle çok ilginç bir gelişme, ama neden önce Vulkan hedeflenmediğini merak ediyorum
Günümüzde daha önemli hedef gibi görünüyor ve onun üzerinde zaten bir OpenGL uygulaması da var
Belirli OpenGL özelliklerini desteklemek için Vulkan sürücüsünün bunlara karşılık gelen özellikleri desteklemesi gerekir ve genelde extension gerekir
Yani sadece temel bir Vulkan sürücüsü gerçekleştirmek size bedavadan OGL 4.6 desteği kazandırmaz; Mesa’nın OGL 4.6’yı Vulkan’a çevirebilmesi için Vulkan sürücüsünde OGL 4.6 özelliklerinin tamamını gerçekleştirmek gerekir
Üstelik Alyssa daha önce tersine mühendislik ve OpenGL sürücüsü projeleri yapmış biri
Ayrıntıları bilmiyorum ama alışık olunan bir API için sürücü yazmak, alışık olunmayan bir API için sürücü yazmaktan büyük ihtimalle çok daha kolay ve hızlıdır
Buradan daha yeni OpenGL’e çıkmanın, tam bir Vulkan uygulaması yapmaktan daha az iş olması çok muhtemel; ayrıca Vulkan için gereken pek çok şeyi de bu süreçte öğrenmişlerdir
Bu yüzden daha hızlı çalışan bir şey elde etmek adına önce daha düşük bir OpenGL sürümünü seçmiş gibi görünüyor
90'larda John Carmack Quake II'de OpenGL kullanmakta ısrar etmemiş olsaydı, 3D oyunlarda OpenGL'in bu kadar görünürlük kazanamayabileceğini düşünmek oldukça şaşırtıcı
OpenGL'i sonuçta olduğu şeye dönüştüren, SGI ve birçok sistem ile mimaride uyumlu uygulamalar oluşturmak için verilen devasa çabaydı
https://web.archive.org/web/19970707113513/http://www.opengl.org/
3D oyunlarla ilgili birçok şeyi Doom ve Quake'e borçluyuz
Microsoft'un API'yi iyileştirmek için büyük uyumsuz değişiklikleri yapmaya devam etme cesaretine sahip olduğunu, OpenGL'in ise uyumluluk kaygıları nedeniyle geri kaldığını düşünüyordu
Direct3D'nin multithreading'i daha iyi ele aldığını ve modern sürümlerinin durum yönetiminde de daha iyi olduğunu söylemişti
Yine de id Software'in OpenGL'de kalmasının nedeninin ataletten kaynaklandığını, avantajlarına rağmen Direct3D'ye geçme planları olmadığını söylemişti
Kaynak: https://www.bit-tech.net/news/gaming/pc/carmack-directx-better-opengl/1/