Özet
Vulkan, 3D grafik işleme ve hesaplama için kullanılan düşük seviyeli çapraz platform bir grafik API ve standardıdır. Aslında o, OpenGL’in eksikliklerini kapatan ve kullanıcıya GPU üzerinde daha fazla kontrol sağlayan bir API’dır. Günümüzün belki de en popüler grafik API’ı olduğunu söyleyebiliriz. Bu kitap, halihazırda C++ bilen ve grafik programlama ile az da olsa ilgilenmiş kişiler için bir Vulkan’a başlangıç kitabıdır. Kitaptaki tüm bölümler aslında tek bir örneği tamamlamak üzerine yazılmıştır: Ekrana bir üçgen çizmek. Hemen hemen her grafik API’ının bir "Hello World" uygulaması diyebileceğimiz bu uygulama ile Vulkan temellerini öğretmeyi amaçlamıştır. Elbette Vulkan’ın kullanıcıya sağladığı kontrol fazla olduğu için, bu gibi basit görünen bir örnek bile sayfalarca anlatıma ve satırlarca koda sahip olabilmektedir.
İnceleme
Bölüm 1: Getting Started with the NextGen 3D Graphics API (Gelecek Nesil 3D Grafik API’ına Başlama)
Bu bölümde öncelikle Vulkan API’ının ne olduğundan, onun tarihi evriminden ve OpenGL ile arasındaki farklardan bahsedilmektedir. Daha sonra kitaba devam etmeden Vulkan için kullanılan önemli jargonlar açıklanmaktadır. Vulkan ile ilgili şu temel bilgiler verilmektedir:
- Vulkan’ın çalışma modeli
- Vulkan’da kuyruklar (queues)
- Nesne modeli
- Nesne ömrü (life-time) ve komut söz dizimi
- Hata kontrolü ve doğrulama
Sonrasında ise bir Vulkan uygulamasında yer alan sürücü (driver), uygulama katmanı (application layer), WSI, SPIR-V ve LunarG SDK gibi kavramların ne anlama geldiği açıklanmaktadır. Bir sonraki kısımda Vulkan’ın programlama modeli hakkında bilgiler verilmektedir. Bu modele göre şu alt bileşenler açıklanıp bölüm sonlandırılmaktadır:
- Donanımın ilklendirilmesi
- Sunum yüzeyinin pencereye alınması
- Kaynakların yüklenmesi
- İş hattının (pipeline) yüklenmesi
- Komutların kaydedilmesi
- Komutların iletilmesi
Bölüm 2: Your First Vulkan Pseudo Program (İlk Vulkan Sözde Programı)
Bu bölümde öncelikle Vulkan’ın sisteminize kurulumu ile ilgili bilgiler verilmektedir. Daha sonra kitap boyunca bölüm bölüm implement edeceğiniz "Hello World" uygulamasının sözde kodları verilmektedir. Bu sözde kod sırasına göre yazacağınız örnek şu alt başlıklar altında incelenmektedir:
- Donanımı ilklendirme ve donanım ile el sıkışma
- Swapchain’i ilklendirme
- Shader’ları sağlama ve onları SPIR-V olarak derleme
- Yerleşim planlarını (layout) inşa etme
- Render geçişlerini (render pass) oluşturma
- Framebuffer oluşturma
- Geometriyi gönderme, Vertex verilerini GPU belleğine yollama
- İş hattı durum yönetimini (pipeline state management) implement etme
- Render geçişini çalıştırma ve çizimi gerçekleştirme
- İşleri kuyruklar yoluyla iletme ve senkronizasyonu sağlama
- Render ettiğiniz şeyi ekranda (sunum katmanında) gösterme
Bölümün sonunda ise bütün bu açıklanan sözde kod adımlarını içeren çalışma modelinin bir diyagramı gösterilmektedir.
Bölüm 3: Shaking Hands with the Device (Aygıt ile El Sıkışma)
Bu bölümde öncelikle LunarG SDK’i ve bu SDK içerisindeki dizin hiyerarşisi hakkında bigiler verilmektedir. Daha sonra CMake ile örnek projenin ilk iskeletini oluşturma anlatılmaktadır. Vulkan’da eklentiler (extensions) ve katmanlar (layers) açıklanmakta, bunlarla ilgili örnek kodların yazımı gösterilmektedir. Projenizde bir Vulkan Instance’ını nasıl oluşturabileceğiniz anlatılmakta ve örnek implementasyonu verilmektedir. Fiziksel (physical) ve mantıksal (logical) cihaz kavramları arasındaki farklar anlatılmaktadır. Kuyruklar (queues) ve Vulkan’da bulunan kuyruk türleri açıklanmakta, örneğiniz için bir kuyruğu nasıl oluşturabileceğiniz gösterilmektedir. En sonunda ise aygıtlar ve kuyruklar ile ilgili anlatılanlar bir araya toplanmaktadır.
Bölüm 4: Debugging in Vulkan (Vulkan’da Hata Ayıklama)
Bu bölümde öncelikle Vulkan’da hata ayıklama için gereken katmanlar açıklanmaktadır. LunarG’de yer alan doğrulama katmanları (validation layers) ve onların özellikleri tek tek anlatılmaktadır. Vulkan uygulamanıza hata ayıklama mekaniğini nasıl yerleştirebileceğiniz kod örnekleri ile gösterilmektedir.
Bölüm 5: Command Buffer and Memory Management in Vulkan (Vulkan’da Komut Tamponu ve Bellek Yönetimi)
Bu bölümde öncelikle Vulkan’da komut tamponu (command buffer), birincil komut tamponu, ikincil komut tamponu ve komut tamponu havuzu (command buffer pool) kavramları açıklanmaktadır. Komutlar arasında açık bir şekilde nasıl senkronizasyonun sağlanabileceği gösterilmektedir. Üç komut kategorisi (eylem, durum yönetimi, senkronizasyon) açıklanmakta ve çalışma sırası mantığı anlatılmaktadır. Daha sonra bu bilgiler ile ilgili Vulkan API’ında yer alan tür ve fonksiyonlar gösterilmektedir.
Komutları bir komut tamponuna nasıl kaydedebileceğiniz açıklanmakta, bu komut tamponlarının kuyruğa gönderilmesi ve kuyruğun beklenmesi ile ilgili fonksiyonlar gösterilmektedir. Daha sonra komut tamponunun örnek projemizdeki sarmalayıcı sınıfının tasarımı ve implementasyonu gösterilmektedir. Bölümün sonunda ise Vulkan’da bellek yönetimi hakkında bilgiler verilmekte ve şu konular ile ilgili konuşulmaktadır:
- Host belleği
- Aygıt (device) belleği
- Aygıt belleğinden yer ayırma (allocate)
- Aygıt belleğinden ayrılan alanı geri bırakma (free)
- Aygıt belleğine host tarafından erişme
- Tembelce (lazily) ayrılmış bellek
Bölüm 6: Allocating Image Resources and Building a Swapchain withWSI (Resim Kaynaklarını Ayırma ve WSI ile Swapchain Kurulumu)
Bu bölümde öncelikle resim kaynakları anlatılmakta ve ek (attachment), kaplama (texture), resim (image), resim yerleşim planı (image layout) gibi kavramların ne olduğuna değinilmektedir. Daha sonra Vulkan’da bir resim kaynağı, resim yerleşim planı ve resim görünümü (image view) oluşturma/silme ile ilgili komutlara bakış atılmaktadır. Bellekte yer ayırarak, bu ayrılan yere resim kaynaklarını bağlama konusu hakkında bilgiler verilmektedir.
İlerleyen kısımlarda ise Swapchain kavramına giriş yapılmakta ve Vulkan’da bir Swapchain oluşturma aşamaları gösterilmektedir. Genel olarak şu 16 aşama hakkında bilgiler verilmekte ve bu aşamalardan bazıları alt bölümlerde ayrıntılandırılmaktadır:
- Boş bir pencere oluşturma
- Swapchain ile ilgili eklentileri (extensions) sorgulama
- Yüzey (surface) oluşturma ve bunu oluşturulan pencere ile ilişkilendirme
- Desteklenen resim formatlarını elde etme
- Swapchain’in resim yüzeyi yeteneklerini sorgulama
- Sunuş modu (present mode) bilgisini yönetme
- Swapchain’i oluşturup sunulan resimleri alma
- Renk ile ilgili resim görünümlerini (image views) oluşturma
- Derinlik ile ilgili resim görünümlerini (image views) oluşturma
- Derinlik resmi ile ilgili bellek ayrımı yapma
- Komut havuzu (command pool) oluşturma
- Komut tamponu (command buffer) oluşturma
- Resim yerleşim planını (image layout) uygulama
- İş hattı bariyerlerini (pipeline barriers) ekleme
- Komut tamponuna kaydetme işlemini sonlandırma
- Derinlikle ilgili bir resim görünümü (image view) oluşturma
Bölüm 7: Buffer Resource, Render Pass, Framebuffer, and Shaderswith SPIR-V (Tampon Kaynağı, Render Geçişi, Framebuffer ve SPIR-V ile Shader’lar)
Bu bölümde öncelikle Vulkan’daki tampon (buffer) kaynaklarının türleri üzerinde durulmakta ve bir tampon kaynağını oluşturma ile bir tampon görünümünü (buffer view) oluşturma komutları gösterilmektedir. Daha sonra bir tampon kaynağına çizilecek geometriyi nasıl gönderebileceğimiz örneklerle açıklanmaktadır. Sonraki kısımda Render geçişi (render pass) kavramı anlatılmakta ve bu kavrama ait ek (attachment) ve alt geçiş (subpass) gibi terminolojiler açıklanmaktadır. Daha sonra bir render geçişi oluşturma ile ilgili Vulkan komutları gösterilmekte ve genel örnek üzerinde implementasyonlar yapılmaktadır.
Oluşturulan Render geçişi ile bir Framebuffer’ı nasıl oluşturulabileceğiniz anlatılmakta ve kod örneği gösterilmektedir. Bu aşamadan sonra ekran ile ilgili ilk görsel işlem olan ekranı bir renk ile temizleme olayı anlatılmaktadır. Son kısımda ise Shader konusuna girilmekte ve Vulkan’daki bazı Shader türleri açıklanmaktadır. SPIR-V aracı ve kütüphanesi anlatılmakta ve SPIR-V ile bir GLSL Shader’ını nasıl derleyebileceğiniz gösterilmektedir.
Bölüm 8: Pipelines and Pipeline State Management (İş Hatları ve İş Hattı Durum Yönetimi)
Bu bölümde öncelikle Vulkan’da iş hattı (pipeline) kavramından bahsedilmekte ve grafik (graphics) ile hesaplama (compute) iş hatları arasındaki farklara değinilmektedir. Genel örneğimizde iş hattının implementasyonu, iş hattının ön belleğe alınması, bir grafik iş hattının oluşturulması gibi konular incelenmekte ve kod örnekleri verilmektedir. Daha sonra hesaplama iş hatları ile ilgili kısa bilgiler verilmektedir. Son kısımda ise iş hattı durum nesneleri (pipeline state objects, PSO) konusuna girilmektedir. Bu kısımda aşağıdaki nesneler ayrıntılı bir şekilde incelenmektedir:
- Dinamik durum (dynamic state)
- Vertex girdisi durumu (vertex input state)
- Girdi montajı durumu (input assembly state)
- Pikselleştirme durumu (rasterization state)
- Renk karışımı durumu (color blend state)
- Görüş alanı durumu (viewport state)
- Derinlik/kalıp durumu (depth/stencil state)
- Çoklu örnekleme durumu (multisampling state)
Bölüm 9: Drawing Objects (Nesneleri Çizdirme)
Bu bölümde öncelikle Vulkan’da çizim yapmanın genel prosedürü açıklanmaktadır. Daha sonra nesneyi çizmeden önce yapılan bazı işlemler incelenmektedir. İncelenen işlemler şöyledir:
- Render geçişi komutlarını kaydetme
- İş hattı (pipeline) nesnesini bağlama
- Çizilecek olan nesnenin geometri bilgilerini belirtme
- Bir dinamik görüş alanı (viewport) tanımlama
- Makaslama (scissoring)
- Çizim komutuyla çizimi gerçekleştirme
Sonraki kısımda normal bir nesnein ekrana çizilmesi ile ilgili bazı Vulkan komutlarının ayrıntıları verilmektedir. Daha sonra ise indisli nesnelerin ekrana çizdirilmesi açıklanmaktadır. Fence, Semaphore ve Event gibi Vulkan’da bulunan senkronizasyon nesneleri ve onların kullanım alanları hakkında bazı bilgiler verilmektedir. En son ise ekranı yeniden boyutlandırıdığınızda çizimi buna göre nasıl ayarlayabileceğiniz ile ilgili örnek gösterilmektedir.
Bölüm 10: Descriptors and Push Constant (Açıklayıcılar ve Push Constant’lar)
Bu bölümde öncelikle açıklayıcı (descriptor) kavramının ne olduğundan ve örnek uygulamada açıklayıcılar ile ilgili sınıfın arayüzünden bahsedilmektedir. Bir açıklayıcı kümesini (descriptor set) nasıl oluşturabileceğiniz, onun yerleşim planını (layout) nasıl ayarlayabileceğiniz, iş hattı yerleşim planını (pipeline layout) nasıl oluşturabileceğiniz ve silebileceğiniz, açıklayıcı havuzunu (descriptor pool) nasıl oluşturabileceğiniz ve silebileceğiniz gibi konular ayrı başlıklar altında açıklanmaktadır. Daha sonra tıpkı OpenGL’de olduğu gibi Uniform’ları Vulkan’da nasıl implement edebileceğiniz gösterilmektedir. Son kısımda ise doğrudan komut tamponu ile Shader’daki sabit değerleri güncellemenize yarayan Push Constant’ları nasıl oluşturabileceğinizden ve Push Constant’lar ile Shader’larda nasıl güncelleme yapabileceğinizden bahsedilmektedir.
Bölüm 11: Drawing Textures (Kaplamaları Çizdirme)
Bu bölümde öncelikle hızlıca resim kaynakları (image resources) ile ilgili anlatılan konuların üzerinden geçilmektedir. Daha sonra sırasıyla Linear Tiling ve Optimal Tiling ile resim kaynaklarının nasıl implement edilebileceği gösterilmektedir. Resim kaynakları ve tampon kaynakları arasında nasıl veri kopyalayabileceğiniz anlatılmakta ve örnekler verilmektedir. Son olarak ise açıklayıcı kümesini (descriptor set) nasıl güncelleyebileceğiniz gösterilmektedir.
Değerlendirme
Bu kitap daha önce grafik programlama ile uğraşmış, C++ bilen ve Vulkan’a giriş yapmak isteyen kişileri hedef alarak yazılmıştır. Yani bu grafik programlamaya başlama kitabı değildir. Zaten grafik programlamaya Vulkan ile başlamak pek tercih edilen bir yol değildir. Çünkü bu kitaptan da anlayabileceğiniz üzere, Vulkan ile bir üçgen çizdirmek bile yüzlerce satır kod yazmanızı gerektirebilir. Kitabın dili çok ağır olmasa da bazı kavramlar üzerinde çok fazla durulmadığından dolayı bazı kısımlar anlaşılmaz hale gelebilir. Bu durum daha önce grafik programlama ile uğraşmış kişiler için de geçerlidir. Çünkü bazı kavramlar Vulkan’a özgüdür veya Vulkan ile değiştirilmiştir. Bu nedenle birkaç yerde internet araştırması yapmanız gerekebilir.
Kitapta çeşitli görsel ve diyagram kullanımı olsa da hem kalite açısından hem de açıklayıcılık açısından bu görseller biraz geri planda kalmaktadır. Genellikle yazı ile çok daha iyi ifade edilebilecek durumlarda görseller kullanılmış, bu da gereksiz bir görsel kullanımına yol açmıştır. Bunları çıkarırsak konuyu açıklamada yardımcı olacak görsellerin varlığı oldukça azdır. Ancak hiç yok da değildir. Bu nedenle görsel ve diyagram kullanımını ortalama seviyede buldum. Bunun dışında görsellerin kalitesi pek iyi olmadığından, görsel üzerindeki bazı yazıların okunması zor bir hale gelebiliyor.
Kitabın içeriği eşsiz değildir. Aksine internet üzerinden ücretsiz bir şekilde erişebileceğiniz web sayfalarında burada anlatılanlar (ve hatta daha fazlası) zaten yer almaktadır. Kitap ile ilgili en fazla eleştirdiğim konu, sistematik anlatımdan çok fonksiyon referanslarına ve açıklamlarına oldukça fazla yer vermesidir. Halbuki Vulkan’ın dokümantasyon sayfalarından bu fonksiyonlar ile alakalı çok daha fazla ve güncel bilgiye erişilebilir. Ancak kitabın büyük bir kısmı bu çok fazla parametreli fonksiyonların, parametrelerini tek tek açıklamakla geçmektedir. Bunun yerine kod ve Vulkan’ın çalışma yapısı ile alakalı açıklamalara daha fazla yer verilseydi daha iyi olabilirdi. Kitap tek bir örnek üzerine ekleme yaparak gitmektedir. Ancak bu Vulkan anlatan kaynaklarda çok da alışılmadık olmadığından, çok olumsuz bir durum olduğunu söyleyemeyiz.
Elbette kitap doğrudan bir örnek üzerinden anlatımı içerdiğinden, amacına göre örnek kulanımının iyi olduğunu söyleyebiliriz. Örneği yapısal programlama yaklaşımında vermek yerine, nesne yönelimli olarak sınıflara ayırmıştır. Bu da bölümlemeyi ve anlatımı kolaylaştırmıştır. Her bölümde örneğin üstüne biraz daha eklenerek ilerlenmiştir. GitHub reposunda her bölümde sadece eklenen kısımların kodları yer almaktadır. Bu da karşılaştırma yapmayı kolaylaştırmaktadır. Örnekler konusunda tek eleştirebileceğim konu, bazı fonksiyon kullanımlarının biraz eski kalmasıdır. Bu da sizin yazılmış örneği test ederken bazı derleme ve çalışma zamanı hataları ile karşılaşabileceğiniz anlamına gelmektedir. Ancak bu durum çok fazla yerde karşınıza çıkmamaktadır. Mümkün olduğunca kitaptakine yakın versiyonlar tercih etmek sizi bu durumdan bir nebze olsun kurtaracaktır.
Sonuç olarak, halihazırda OpenGL gibi diğer grafik API’ları ile uğraşmış, grafik programlama ile ilgilenen ve Vulkan’a bir giriş yapmak isteyen birisiyseniz bu kitaba bir göz atabilirsiniz. Ancak bu kitaba erişemediyseniz bile internet üzerinden benzer konuları anlatan ücretsiz web siteleri bulabilirsiniz. Kitabın anlatım dili çok ağır olmasa da bazı kavramları açıklamadan anlatım yaptığı için anlaşılabilirlik sorunları meydana gelebilir. Kitapta görsel ve diyagram kullanılsa da bu çok etkili yapılamamıştır. Bazı görseller gereksiz, bazılarının ise kalitesi düşüktür. Kitapta fonksiyon referanslarına gereğinden fazla alan ayrıldığı için içerik kalitesinin çok iyi olduğunu söyleyemeyiz. Kitap bir örneğin üzerine koyarak ilerlemekte ve nesne yönelimli programlama mantığı ile örneği implement etmektedir. Bu da kitabın en iyi özelliklerinden biridir diyebiliriz.
Learning Vulkan İnceleme Özeti

Basım No: 1st Edition
Yazarlar: Parminder Singh
Yayımlama Tarihi: 15 Aralık 2016
Sayfa Sayısı: 466
Sonuç Özeti
Sonuç olarak, halihazırda OpenGL gibi diğer grafik API’ları ile uğraşmış, grafik programlama ile ilgilenen ve Vulkan’a bir giriş yapmak isteyen birisiyseniz bu kitaba bir göz atabilirsiniz. Ancak bu kitaba erişemediyseniz bile internet üzerinden benzer konuları anlatan ücretsiz web siteleri bulabilirsiniz. Kitabın anlatım dili çok ağır olmasa da bazı kavramları açıklamadan anlatım yaptığı için anlaşılabilirlik sorunları meydana gelebilir. Kitapta görsel ve diyagram kullanılsa da bu çok etkili yapılamamıştır. Bazı görseller gereksiz, bazılarının ise kalitesi düşüktür. Kitapta fonksiyon referanslarına gereğinden fazla alan ayrıldığı için içerik kalitesinin çok iyi olduğunu söyleyemeyiz. Kitap bir örneğin üzerine koyarak ilerlemekte ve nesne yönelimli programlama mantığı ile örneği implement etmektedir. Bu da kitabın en iyi özelliklerinden biridir diyebiliriz.




