Bir WebGL geliştiricisi olarak, modern grafik API'lerinin ilerlemelerini web'e taşıyan WebGL'nin halefi WebGPU'yu kullanmaya başlamaktan hem çekinebilir hem de heyecan duyabilirsiniz.
WebGL ve WebGPU'nun birçok temel kavramı paylaştığını bilmek rahatlatıcıdır. Her iki API de GPU'da gölgelendirici adı verilen küçük programlar çalıştırmanıza olanak tanır. WebGL, köşe ve parça gölgelendiricileri desteklerken WebGPU, hesaplama gölgelendiricilerini de destekler. WebGL, OpenGL Shading Language'i (GLSL) kullanırken WebGPU, WebGPU Shading Language'i (WGSL) kullanır. İki dil farklı olsa da temel kavramlar çoğunlukla aynıdır.
Bu makalede, başlamanıza yardımcı olmak için WebGL ve WebGPU arasındaki bazı farklar vurgulanmaktadır.
Global durum
WebGL'de çok fazla genel durum vardır. Hangi dokuların ve arabelleklerin bağlandığı gibi bazı ayarlar tüm oluşturma işlemleri için geçerlidir. Bu genel durumu çeşitli API işlevlerini çağırarak ayarlarsınız ve siz değiştirene kadar geçerli kalır. WebGL'deki genel durum, genel bir ayarı değiştirmeyi unutmak kolay olduğundan büyük bir hata kaynağıdır. Ayrıca, geliştiricilerin global durumu kodun diğer kısımlarını etkileyecek şekilde yanlışlıkla değiştirmemeye dikkat etmesi gerektiğinden global durum, kod paylaşımını zorlaştırır.
WebGPU, durumsuz bir API'dir ve genel bir durumu korumaz. Bunun yerine, WebGL'de genel olan tüm oluşturma durumunu kapsüllemek için işlem hattı kavramını kullanır. Bir işlem hattı, hangi karıştırmanın, topolojinin ve özelliklerin kullanılacağı gibi bilgileri içerir. Ardışık düzenler sabittir. Bazı ayarları değiştirmek istiyorsanız başka bir işlem hattı oluşturmanız gerekir. WebGPU, komutları birlikte gruplandırmak ve kaydedildikleri sırayla yürütmek için komut kodlayıcıları da kullanır. Örneğin, gölge eşlemede bu özellikten yararlanılır. Uygulama, nesneler üzerinde tek bir geçişte her ışığın gölge eşlemesi için bir tane olmak üzere birden fazla komut akışı kaydedebilir.
Özetlemek gerekirse WebGL'nin global durum modeli, sağlam ve birleştirilebilir kitaplıklar ile uygulamalar oluşturmayı zor ve kırılgan hale getirdiğinden WebGPU, geliştiricilerin GPU'ya komut gönderirken takip etmesi gereken durum miktarını önemli ölçüde azalttı.
Artık senkronize etme
GPU'larda, komutları gönderip senkron olarak beklemek genellikle verimsizdir. Bu işlem, işlem hattını temizleyip kabarcıklara neden olabilir. Bu durum, özellikle GPU sürücüsünün JavaScript'ten ayrı bir işlemde çalıştığı çoklu işlem mimarisini kullanan WebGPU ve WebGL'de geçerlidir.
Örneğin, WebGL'de gl.getError()
işlevinin çağrılması için JavaScript işleminden GPU işlemine ve tekrar geri eşzamanlı bir IPC gerekir. Bu durum, iki işlem iletişim kurarken CPU tarafında bir kabarcığa neden olabilir.
WebGPU, bu kabarcıkları önlemek için tamamen eşzamansız olacak şekilde tasarlanmıştır. Hata modeli ve diğer tüm işlemler eşzamansız olarak gerçekleşir. Örneğin, bir doku oluşturduğunuzda, doku aslında hatalı olsa bile işlem hemen başarılı olmuş gibi görünür. Hatayı yalnızca eşzamansız olarak keşfedebilirsiniz. Bu tasarım, süreçler arası iletişimi sorunsuz hale getirir ve uygulamalara güvenilir performans sağlar.
İşlem gölgelendiricileri
Compute shader'lar, genel amaçlı hesaplamalar yapmak için GPU'da çalışan programlardır. Yalnızca WebGL'de değil, WebGPU'da kullanılabilir.
Köşe ve parça gölgelendiricilerin aksine, bunlar grafik işleme ile sınırlı değildir ve makine öğrenimi, fizik simülasyonu ve bilimsel hesaplama gibi çok çeşitli görevler için kullanılabilir. İşlem gölgelendiriciler, yüzlerce hatta binlerce iş parçacığı tarafından paralel olarak yürütülür. Bu da onları büyük veri kümelerini işlemek için çok verimli hale getirir. GPU hesaplama ve WebGPU hakkında bu kapsamlı makalede daha fazla bilgi edinin.
Video karesi işleme
JavaScript ve WebAssembly kullanarak video karelerini işlemek bazı dezavantajlara sahiptir: verileri GPU belleğinden CPU belleğine kopyalama maliyeti ve çalışanlar ile CPU iş parçacıklarıyla elde edilebilecek sınırlı paralellik. WebGPU'da bu sınırlamalar yoktur. Bu nedenle, WebCodecs API ile sıkı entegrasyonu sayesinde video karelerini işlemek için idealdir.
Aşağıdaki kod snippet'inde, WebGPU'da VideoFrame'in harici doku olarak nasıl içe aktarılacağı ve işleneceği gösterilmektedir. Bu demoyu deneyebilirsiniz.
// Init WebGPU device and pipeline...
// Configure canvas context...
// Feed camera stream to video...
(function render() {
const videoFrame = new VideoFrame(video);
applyFilter(videoFrame);
requestAnimationFrame(render);
})();
function applyFilter(videoFrame) {
const texture = device.importExternalTexture({ source: videoFrame });
const bindgroup = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [{ binding: 0, resource: texture }],
});
// Finally, submit commands to GPU
}
Varsayılan olarak uygulama taşınabilirliği
WebGPU, limits
isteğinde bulunmanızı zorunlu kılar. requestDevice()
, varsayılan olarak fiziksel cihazın donanım özellikleriyle eşleşmeyebilen ancak tüm GPU'ların makul ve en düşük ortak paydası olan bir GPUDevice döndürür. WebGPU, geliştiricilerin cihaz sınırları istemesini zorunlu kılarak uygulamaların mümkün olduğunca çok cihazda çalışmasını sağlar.
Canvas işleme
WebGL, bir WebGL bağlamı oluşturup alfa, antialias, colorSpace, depth, preserveDrawingBuffer veya stencil gibi bağlam özelliklerini sağladıktan sonra tuvali otomatik olarak yönetir.
Diğer yandan, WebGPU'da tuvali kendiniz yönetmeniz gerekir. Örneğin, WebGPU'da yumuşatma elde etmek için çok örnekli bir doku oluşturup bu dokuya göre oluşturma işlemi yaparsınız. Ardından, çok örnekli dokuyu normal bir dokuya dönüştürür ve bu dokuyu tuvale çizersiniz. Bu manuel yönetim, tek bir GPUDevice nesnesinden istediğiniz kadar tuvale çıkış yapmanıza olanak tanır. Buna karşılık WebGL, tuval başına yalnızca bir bağlam oluşturabilir.
WebGPU Multiple Canvases demosuna göz atın.
Tarayıcıların sayfa başına WebGL tuval sayısı konusunda bir sınırı olduğunu da belirtmek isteriz. Bu makalenin yazıldığı sırada Chrome ve Safari aynı anda yalnızca 16 WebGL tuvali kullanabiliyordu. Firefox ise 200 WebGL tuvali oluşturabiliyordu. Öte yandan, sayfa başına WebGPU tuvali sayısıyla ilgili bir sınırlama yoktur.

Faydalı hata mesajları
WebGPU, API'den döndürülen her mesaj için bir çağrı yığını sağlar. Bu sayede, kodunuzda hatanın nerede oluştuğunu hızlıca görebilirsiniz. Bu, hataları ayıklama ve düzeltme açısından faydalıdır.
WebGPU hata mesajları, çağrı yığını sağlamanın yanı sıra anlaşılması kolay ve uygulanabilir niteliktedir. Hata mesajları genellikle hatanın açıklamasını ve nasıl düzeltileceğine dair önerileri içerir.
WebGPU, her WebGPU nesnesi için özel bir label
sağlamanıza da olanak tanır. Bu etiket daha sonra tarayıcı tarafından GPUError mesajlarında, konsol uyarılarında ve tarayıcı geliştirici araçlarında kullanılır.
Adlardan dizinlere
WebGL'de birçok şey adlarla bağlanır. Örneğin, GLSL'de myUniform
adlı bir tek tip değişken tanımlayabilir ve gl.getUniformLocation(program, 'myUniform')
kullanarak konumunu alabilirsiniz. Üniform değişkenin adını yanlış yazarsanız hata alacağınız için bu özellik kullanışlıdır.
Öte yandan, WebGPU'da her şey tamamen bayt uzaklığı veya dizin (genellikle konum olarak adlandırılır) ile bağlanır. WGSL ve JavaScript'teki kod konumlarını senkronize tutmak sizin sorumluluğunuzdadır.
Mipmap oluşturma
WebGL'de, bir dokunun 0. düzey mip'ini oluşturabilir ve ardından gl.generateMipmap()
işlevini çağırabilirsiniz. WebGL, diğer tüm mip düzeylerini sizin için oluşturur.
WebGPU'da mipmap'leri kendiniz oluşturmanız gerekir. Bunu yapmaya yönelik yerleşik bir işlev yoktur. Karar hakkında daha fazla bilgi edinmek için şartname tartışmasına göz atın. Mipmap'ler oluşturmak için webgpu-utils gibi kullanışlı kitaplıkları kullanabilir veya bunu kendiniz nasıl yapacağınızı öğrenebilirsiniz.
Depolama arabellekleri ve depolama dokuları
Uniform arabellekler hem WebGL hem de WebGPU tarafından desteklenir ve sınırlı boyuttaki sabit parametreleri gölgelendiricilere iletmenize olanak tanır. Depolama arabellekleri, tek tip arabelleklere çok benzese de yalnızca WebGPU tarafından desteklenir ve tek tip arabelleklerden daha güçlü ve esnektir.
Gölgelendiricilere iletilen verileri depolayan depolama arabellekleri, tek tip arabelleklerden çok daha büyük olabilir. Spesifikasyonda, tek tip arabellek bağlamalarının en fazla 64 KB olabileceği belirtilse de (
maxUniformBufferBindingSize
), WebGPU'da depolama arabelleği bağlamasının maksimum boyutu en az 128 MB'tır (maxStorageBufferBindingSize
).Depolama arabellekleri yazılabilir ve bazı atomik işlemleri desteklerken tek tip arabellekler yalnızca salt okunurdur. Bu sayede yeni algoritma sınıfları uygulanabilir.
Depolama arabellekleri bağlamaları, daha esnek algoritmalar için çalışma zamanı boyutlu dizileri desteklerken tek tip arabellek dizisi boyutlarının gölgelendiricide sağlanması gerekir.
Depolama dokuları yalnızca WebGPU'da desteklenir ve dokular için depolama arabellekleri, tek tip arabellekler için depolama arabellekleri gibidir. Normal dokulardan daha esnektirler ve rastgele erişim yazma işlemlerini (gelecekte okuma işlemleri de desteklenecektir) desteklerler.
Arabellek ve doku değişiklikleri
WebGL'de bir arabellek veya doku oluşturabilir, ardından boyutunu istediğiniz zaman değiştirebilirsiniz. Örneğin, arabellek için gl.bufferData()
, doku için gl.texImage2D()
kullanabilirsiniz.
WebGPU'da arabellekler ve dokular sabittir. Bu nedenle, oluşturulduktan sonra bu öğelerin boyutunu, kullanımını veya biçimini değiştiremezsiniz. Yalnızca içeriklerini değiştirebilirsiniz.
Boşlukla ilgili kural farklılıkları
WebGL'de Z klip alanı aralığı -1 ile 1 arasındadır. WebGPU'da Z kırpma alanı aralığı 0 ile 1 arasındadır. Bu durumda, z değeri 0 olan nesneler kameraya en yakın, z değeri 1 olan nesneler ise en uzak nesnelerdir.
WebGL, Y ekseninin yukarı, Z ekseninin ise izleyiciye doğru olduğu OpenGL kuralını kullanır. WebGPU, Y ekseninin aşağı, Z ekseninin ise ekranın dışına doğru olduğu Metal kuralını kullanır. Y ekseni yönünün, çerçeve arabelleği koordinatı, görüntü alanı koordinatı ve parça/piksel koordinatında aşağı doğru olduğunu unutmayın. Klip alanında, Y ekseni yönü WebGL'de olduğu gibi yukarı doğrudur.
Teşekkür
Bu makaleyi inceledikleri için Corentin Wallez, Gregg Tavares, Stephen White, Ken Russell ve Rachel Andrew'a teşekkür ederiz.
WebGPU ile WebGL arasındaki farkları ayrıntılı olarak incelemek için WebGPUFundamentals.org adresini de ziyaret etmenizi öneririz.