大家好,經過這段時間的持續努力,我已將Vulkan的基礎數據結構進行了一輪改造,放在了名為types.h的文件中.

被封裝的就是三類結構:

  • 枚舉常量:
    • enum類型
    • 例如 VkPipelineBindPoint
  • 位標:
    • enum類型
    • 但Vk作為位標使用
    • 例如 VkPipelineCreateFlagBits
  • 結構體:
    • 例如 VkComputePipelineCreateInfo

總的來說,是解決了幾個原始結構不如意的地方:

  1. 最初時,我的願望僅僅是將下邊這兩個麻煩解決一下:
  • VkStructureType sType;
  • const void* pNext;

每個結構的sType是固定的,只需默認初始化就好.

而pNext則不太好辦:

拿VkFenceCreateInfo來說,它的pNext可以指向這兩個結構體:

  • VkExportFenceCreateInfo
  • VkExportFenceWin32HandleInfoKHR

那麼它作為參數放入vkCreateFence這個Api之前,可以這麼做:

VkFenceCreateInfo fence_ci{...};
VkExportFenceCreateInfo fence_eci{...};
VkExportFenceWin32HandleInfoKHR fence_w32eci{...};
fence_ci.pNext = &fence_eci;
fence_eci.pNext = &fence_w32eci;

這樣就形成一個鏈,而Api內部也就依靠它們各自的sType來識別類型,進行處理.

如果你是新手,那麼你使用原始的結構時,就需要查資料,才能知道這裡邊能放入什麼.

我的修改,就是想讓使用者僅依靠智能提示,就能清楚的知道自己能做什麼:

(試過繼承基類 重載運算符 兩種方式 無奈IDE的智障提示太傻 只能做成成員函數.)

2. 修改位標

位標在Vulkan中就是一個enum,缺點是不夠安全. 另外一個就是不夠方便.

現在它可以這樣用:

還可以這樣用:

3.修改枚舉

沒做什麼特別的,僅僅是把它保護起來了:

4.命名規則

這三種類型在Vulkan中都是用Vk開頭,

位標還算好識別,都是FlagBits結尾,Flags則表示多個FlagBits按位或運算的結果.

那麼枚舉與struct就不是一眼看明白了.

那我改成了前綴表示:

一眼就明白.

總之,要解決最關鍵的pNext問題->就得將它設為私有

那有兩條路可走.

  • 私有繼承,然後再用什麼set() get()函數完成對每個成員的賦值和取值
  • 另搞一套同樣成員的結構體

兩條路各有各的麻煩,官方Hpp就是走的後者.我也選擇的後者.

但不論前者後者,都是要生成代碼的,手寫的話,用宏可能會輕鬆些,但會很過分.

採取生成代碼的方式除了會很長以外,反而清晰明瞭得多.

最終我用來生成代碼的文件是vk_types.py

python給我的體驗是庫用得爽,方便.但限於用這個的水平,我很容易寫出垃圾代碼.目前我心目中給它的定位是:天然的shell替代品.

Vulkan的介面必須是C的,而C裡面的一些東西放到C++裡邊來,就有各種各種的改造方式.

如果有人問C和C++有什麼不同? 我會把它個作為一個典型的例子.

感謝大家閱讀! 完畢.

項目地址:

gchihiha/laka_vulkan?

github.com圖標
推薦閱讀:

相關文章