1. 程式人生 > >Vulkan Cookbook 第四章 1 建立緩衝區

Vulkan Cookbook 第四章 1 建立緩衝區

建立緩衝區

譯者注:示例程式碼點選此處

緩衝區是最簡單的資源,因為他們代表的資料只能線形佈局在記憶體中,就像典型的C/C++陣列一樣:

緩衝區可用於各種目的。它們可以通過描述符集在管道中用於統一緩衝區,記錄緩衝區或紋理緩衝區等資料儲存。它們可以是頂點索引或屬性的資料來源,也可以用作分段資源-用於從CPU到GPU的資料傳輸的中間資源。出於所有這些目的,我們只需要建立一個緩衝區並制定其用法。

怎麼做...

1.獲取已建立的裝置邏輯控制代碼,將其儲存在名為logical_device的VkDevice型別變數中。
2.建立一個名為size的VkDeviceSize型別的變數,該變量表示緩衝區能夠儲存的資料大小。
3.考慮將使用的緩衝區的所需方案。建立名為usage的VkBufferUsageFlags位域型別變數。
4.建立名為buffer_create_info的VkBufferCreateInfo型別的變數。將以下值分配給其成員:
  ·sType為VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
  ·pNext為nullptr value
  ·flags為0
  ·usage為usage
  ·sharingMode為VK_SHARING_MODE_EXCLUSIVE
  ·queueFamilyIndexCount為0
  ·pQueueFamilyIndices為nullptr
5.建立一個名為buffer的VkBuffer型別的變數,其中將儲存建立的緩衝區的控制代碼。
6.呼叫vkCreateBuffer( logical_device, &buffer_create_info, nullptr, &buffer ),並在第一個引數中提供邏輯裝置控制代碼,在第二個引數中提供指向buffer_create_info變數的指標,第三個引數為nullptr,以及最後一個引數指向緩衝區變數。
7.通過檢查返回的值是否等於VK_SUCCESS,確保函式呼叫成功。

這個怎麼運作...

在我們建立緩衝區之前,需要知道緩衝區應該有多大以及想要如何使用緩衝區。緩衝區大小由我們希望儲存在其中的資料決定。緩衝區在應用程式中使用的方式由緩衝區的用法指定。我們不能以緩衝區建立期間未定義的方式使用緩衝區。

提示:緩衝區只能在建立期間指定用途(用法)。

以下是可以使用緩衝區的受支援方式列表:
  ·VK_BUFFER_USAGE_TRANSFER_SRC_BIT表示緩衝區可以是複製操作的資料來源
  ·VK_BUFFER_USAGE_TRANSFER_DST_BIT表示可以將資料賦值到緩衝區
  ·VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT表示緩衝區可以在著色器中用作統一紋理緩衝區
  ·VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT表示緩衝區可以在著色器中用作儲存紋理緩衝區
  ·VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT表示緩衝區可以在著色器中用作統一變數的值來源
  ·VK_BUFFER_USAGE_STORAGE_BUFFER_BIT表示可以在著色器中將數儲存在緩衝區中
  ·VK_BUFFER_USAGE_INDEX_BUFFER_BIT表示緩衝區可以在繪製期間用作頂點索引資料來源
  ·VK_BUFFER_USAGE_VERTEX_BUFFER_BIT表示緩衝區可以是繪圖期間指定的頂點屬性的資料來源  
  ·VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT表示緩衝區可以包含間接繪製期間將使用的資料

要建立緩衝區,我們需要準備一個VkBufferCreateInfo型別的變數,在其中提供以下資料:

VkBufferCreateInfo buffer_create_info = { 
  VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, nullptr,
  0,
  size,
  usage, 
  VK_SHARING_MODE_EXCLUSIVE, 
  0,
  nullptr
};

size和usage變數分別定義了緩衝區可以容納的資料量以及我們在應用程式中使用緩衝區的方式。

為sharingMode成員提供前面的VK_SHARING_MODE_EXCLUSIVE值是另一個非常重要的引數。通過它我們指定來自多個族的佇列是否可以同時訪問緩衝區。獨佔共享模式(Exclusive sharing mode)告訴驅動程式緩衝區只能由一個族中的佇列引用一次,我們必須明確告訴驅動程式何時所有權發生了變換(當我們將所有權從一個族轉移到另一個族時)。這個選項給了我們更好的效能,但需付出了更多的工作。

我們還可以指定共享模式(VK_SHARING_MODE_CONCURRENT)有了它來自多個族的多個佇列可以同時訪問緩衝區,我們不需要執行所有權轉移。但是需要權衡的是,併發訪問可能具有較低的效能。

在我們準備好建立資料之後,可以建立一個這樣的緩衝區:

VkResult result = vkCreateBuffer( logical_device, &buffer_create_info, nullptr, &buffer ); 
if( VK_SUCCESS != result ) {
  std::cout << "Could not create a buffer." << std::endl;
  return false; 
}
return true;