Vulkan Tutorial 4 建立命令緩衝區

2021-09-03 01:10:09 字數 2951 閱讀 4571

基本命令緩衝區操作

opengl裡面設定線寬的時候,是通過呼叫gllinewidth()。如下圖所示,驅動程式將這個api呼叫轉換為特定於gpu的指令,並且放入命令緩衝區。驅動程式負責管理這個緩衝區的建立和銷毀,並且負責將命令緩衝傳送給gpu去處理緩衝裡面指令,應用程式不需要關心這些操作。

在vulkan裡面,呼叫vkcmdsetlinewidth()來設定線寬。此函式實際上是新增乙個指令到命令緩衝區。因為不同的gpu都有特定的指令集,因此,驅動程式需要將這些指令翻譯為gpu可識別的指令。

命令緩衝池(command buffer pools)

在vulkan裡面,建立和銷毀命令緩衝區的代價比較高昂,因此,vulkan提出了命令緩衝池的概念。命令緩衝池負責管理命令緩衝區。一下是官網給出的使用命令緩衝池的原因:

應用程式可能只是很短暫的使用命令緩衝區。如果沒有緩衝池,為了節約資源,可能會頻繁的建立和銷毀命令緩衝區。此處類似記憶體池的概念。

命令緩衝區是一塊特殊的記憶體,此記憶體需要被cpu和gpu同時訪問。某些系統裡面,記憶體到處理器的對映需要用到很大一塊記憶體,因此,乙個很小的命令緩衝區可能需要使用很大一塊記憶體來對映。

記憶體對映的代價很昂貴,因為記憶體對映會改變頁表以及使tlb(translation lookaside buffer)失效。因此需要一次性對映乙個比較大的記憶體,而不是每次都對映一小塊。關於tlb的解釋,參考

命令緩衝池和佇列族

硬體負責讀取命令緩衝記憶體,而不同的gpu硬體有自己的記憶體分配屬性,驅動程式需要根據這個屬性來建立命令緩衝池。

如果乙個gpu有多個硬體佇列(上一節有講解),並且這些硬體佇列具有不同的記憶體分配屬性,那麼,驅動程式需要為這些硬體佇列單獨建立對應記憶體分配屬性的命令緩衝池。從官方文件來看,乙個硬體佇列,應該就是乙個佇列族。如果硬體佇列有自己特有的記憶體分配屬性,那麼,乙個記憶體緩衝池則只能對應乙個硬體佇列,也就是乙個佇列族。

建立命令緩衝池的函式宣告如下:

vkapi_attr vkresult vkapi_call vkcreatecommandpool(

vkdevice device,

const vkcommandpoolcreateinfo* pcreateinfo,

const vkallocationcallbacks* pallocator,

vkcommandpool* pcommandpool

);

建立命令緩衝池的方法如下:

vkcommandpoolcreateinfo cmd_pool_info = {};

cmd_pool_info.stype = vk_structure_type_command_pool_create_info;

cmd_pool_info.pnext = null;

cmd_pool_info.queuefamilyindex = info.graphics_queue_family_index;

cmd_pool_info.flags = 0;

res = vkcreatecommandpool(info.device, &cmd_pool_info, null, &info.cmd_pool);

因為每個佇列族的記憶體分配屬性都不一樣,所以需要為每乙個佇列族都建立乙個命令緩衝池,以上只為乙個佇列族建立了緩衝池。

建立命令緩衝區

建立命令緩衝區函式宣告如下:

vkapi_attr vkresult vkapi_call vkallocatecommandbuffers(

vkdevice device,

const vkcommandbufferallocateinfo* pallocateinfo,

vkcommandbuffer* pcommandbuffers

);

建立命令緩衝區的**也很簡單:

vkcommandbufferallocateinfo cmd = {};

cmd.stype = vk_structure_type_command_buffer_allocate_info;

cmd.pnext = null;

cmd.commandpool = info.cmd_pool;

cmd.level = vk_command_buffer_level_primary;

cmd.commandbuffercount = 1;

res = vkallocatecommandbuffers(info.device, &cmd, &info.cmd);

使用命令緩衝區對命令緩衝區的使用必須以vkbegincommandbuffer()開頭,以vkendcommandbuffer()函式結尾。vkbegincommandbuffer()函式將命令緩衝區的狀態改變為「錄製」狀態,也就是記錄命令。vkendcommandbuffer()函式告訴vulkan,操作已經完成,命令緩衝區當前的「錄製」狀態將變為「準備」狀態。在呼叫這兩個函式之間,可以呼叫一些列vkcmd*函式往命令緩衝區插入命令,比如:vkcmdsetlinewidth()和vkcmddraw()。

命令緩衝區進入「準備」狀態後,gpu此時還不會做任何事情。為了讓gpu開始執行這些指令,必須呼叫vkqueuesubmit()函式,將命令緩衝區提交到gpu的佇列中。在將命令緩衝區提交到佇列之前,還有很多事情要做,此是後話。

Vulkan Tutorial 9 描述符集合

在上一節定義了乙個描述符集合布局,但是並沒有實際建立。描述符集合用於告訴gpu,uniform buffer是如何對映到著色器程式的uniform變數。本節介紹描述符集合的建立和初始化。與明亮緩衝類似,描述符集合也是衝池裡面建立的,所以必須先建立乙個池。對於乙個uniform buffer,只需要乙...

小公尺電視4a4c4x4s的區別

小公尺電視4a 55英吋延續了小公尺電視以往的簡約時尚風格英吋,採用黑色色彩為主,看起來經典又百搭 搭配64位四核處理器,配置2gb 8gb大儲存 搭載第6代畫質引擎,相比上一代有4處公升級,同步支援hdr10和hybrid log gamma。提供了更多的動態範圍和影象細節,使得暗部更暗,亮部更亮...

SpringMVC4 Hibernate4學習筆記

注 本文是以前幾篇部落格的簡單合併,未做更新 鑑於目前資料大多數都是基於spring3的配置,本人在最初搭建的時候遇到很多問題,由此記錄下來僅供參考 使用的jar檔案springframework4.0.6 為了方便整個先導入 hibernate4.3.6 required 下所有jar 以及 op...