Vulkan Cookbook 第五章 7 建立統一(uniform)緩衝區
建立統一緩衝區
譯者注:示例程式碼點選此處
在Vulkan中著色器中使用的統一(uniform)變數不能放在全域性名稱空間中。它們只能在統一緩衝區中定義。我們還需要使用VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT建立緩衝區。
怎麼做...
- 獲取已建立的邏輯裝置控制代碼並用其初始化名為logical_device的VkDevice變數。
- 建立一個名為uniform_buffer的VkBuffer型別變數。它將儲存要建立的緩衝區。
- 使用logical_device變數建立緩衝區並指定所選的大小和用法。必須至少包含一個VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT標誌。將緩衝區的控制代碼儲存在uniform_buffer變數中(請參閱第4章,資源和記憶體中的
- 使用VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT屬性分配記憶體物件(或使用現有記憶體物件的部分範圍)並將其繫結到緩衝區(請參閱第4章,資源和記憶體中的為緩衝區分配和繫結記憶體物件內容)。
這個怎麼運作...
統一緩衝區用於為著色器內的只讀uniform變數提供值。
提示:統一緩衝區使用VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER或VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC描述符型別。
通常,統一緩衝區包含不經常更改的引數資料即矩陣(對於少量資料,推薦使用壓入式常量(push constants)因為更新它們通常要快得多,通過壓入式常量向著著色器提供資料,有關壓入式常量的資訊可以在第9章命令中的命令記錄與繪圖)。
建立一個緩衝區,其中將儲存uniform變數的資料,這要求我們在緩衝區建立期間指定VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT標誌。建立緩衝區時,我們需要準備一個記憶體物件並將其繫結到建立的緩衝區。(也可是使用現有的記憶體物件並將其一部分繫結到緩衝區):
if( !CreateBuffer( logical_device, size, usage | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, uniform_buffer ) ) { return false; } if( !AllocateAndBindMemoryObjectToBuffer( physical_device, logical_device, uniform_buffer, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memory_object ) ) { return false; } return true;
在緩衝區及其記憶體物件準備就緒後,我們可以像使用任何其他型別的緩衝區一樣將資料上傳到它們,只需記住uniform變數必須放在適當的偏移處。這些偏移量與GLSL語言中的std140佈局相同,定義如下:
- 大小為N的標量變數必須放在N的倍數的偏移處
- 具有兩個分量的向量,其中每個分量的大小為N,必須放在2N的倍數偏移處
- 具有三個或四個分量的向量,其中每個分量的大小為N,必須放置在4N的偏移處
- 具有大小為N個元素的陣列放在N的倍數的偏移處,該偏移量必須被舍入到16的倍數。
- 結構體必須被放置在與其成員的最大偏移量相同的偏移量處,該偏移量必須被舍入到16的倍數(具有最大偏移量要求的成員偏移量,舍入到16的倍數)
- 行主序矩陣必須放置在等於向量偏移的偏移處,其中分量數等於矩陣中的列數。
- 列主序矩陣必須放置在與其列相同的偏移處
動態統一(Dynamic uniform)緩衝區與普通緩衝區的不同之處在於它們指定地址的方式。在描述符集更新期間,我們指定應該用於統一緩衝區的記憶體大小以及從緩衝區記憶體開始的偏移量。對於普通的統一緩衝區這些引數保持不變。而對於統一動態緩衝區,指定的偏移量變為從基偏移量(base offset),稍後可以通過在描述符集繫結到命令緩衝區時新增的動態偏移量來修改基偏移。
提示:在GLSL著色器中,統一緩衝區和動態統一緩衝區都使用uniform限定符和塊語法定義。
GLSL著色器中的統一緩衝區定義的示例如下:
layout (set=m, binding=n) uniform <variable name>
{
vec4 <member 1 name>;
mat4 <member 2 name>;
// ...
};