19Vulkan——Pipeline管線

1.管線

管線是指數據輸入流經的一系列固定階段;每個階段都處理傳入的數據並將其傳遞到下一個階段。 最終產品或是一個 2D 柵格繪圖圖像(圖形管線),或是 使用計算邏輯和計算操作(計算管線)更新後的資源(緩衝區或圖像)。

Vulkan 支持兩種類型的管線,即圖形和計算。

  • 圖形管線:graphics pipeline,該管線通過命令緩衝區接收若干 Vulkan 命令並繪製 2D / 3D 場景的 2D 光柵化圖像。
  • 計算管線:compute pipeline,該管線通過命令緩衝區接收 Vulkan 命令並處理它們以進行相關的計算工作。
  1. 管線行程Input Assembler開始,輸入的頂點數據根據指定的基本拓撲結構以點、線和三角形的形式進行組裝。 使用頂點着色器 Vertex Shader可編程階段,輸入的頂點數據被轉換到一個剪輯空間。 幾何圖形在Tessellation Control ShaderTessellation Evaluation Shader裝配器中進行細分。 幾何圖形着色器 Geometry Shader 具有從單個傳入圖元中生成多個圖元的獨特功能。
  2. 接下來,Primitive Assembler從前一階段獲取轉換過的所有座標,並按照輸入階段提供的指定繪圖操作或原始類型(點,線和三角形)信息有序地對它們進行排列。 當關聯的頂點座標落在視景體之外時,圖元就會被裁剪掉,當發生這種情況時,裁剪掉的片段(視野之外)會被丟棄。
  3. 柵格化 Rasterization 是將變換後的屏幕空間圖元(點,線和三角形)轉換爲稱之爲片段的離散元素的過程。 這些片段由下一個階段控制,稱爲片段着色器 Fragment Shader片段着色器在單個片段上執行計算。 這些片段最終會成爲幀緩衝區的一部分,這個幀緩衝區全部經歷了大量條件的更新,例如深度測試,模版測試和片段混合。
  4. 緩衝區和圖像內存類型可以以 1D / 2D / 3D 工作組的形式 (稱爲計算管線)在一個單獨的管線中進行處理。 計算管線在並行處理過程中完成工作的能力是非常強大的;它主要用於圖像處理和物理計算領域。 計算管線可以修改(讀取 / 寫入)緩衝區和圖像內存。

    該管線大致由三個概念組成:管線狀態對象,管線緩存對象和管線佈局。 這些可用於有效控制底層管線的操作:

管線狀態對象(PSO):Pipeline state objects (PSO),物理設備或 GPU 能夠直接在硬件中執行多種操作。 這些操作可能包括光柵化器和條件更新,例如混合深度測試,模版測試等。 Vulkan 在 PSO 的幫助下提供了控制這些硬件設置的能力。 其他基於硬件的操作可能包括:在給定的幾何形狀上組裝基本拓撲類型(點 / 線 / 三角形),視口控制等。

管線緩存對象(PCO):Pipeline cache objects (PCOs),管線緩存提供了更快地檢索和重用存儲過的管線的一種機制。 這爲應用程序避免創建類似或重複的冗餘管線對象提供了一個更好機會。

管線布局:Pipeline layouts,緩衝區和圖像被間接連接到着色器,可以使用着色器資源變量對其進行訪問。 資源變量被連接到緩衝區視圖和圖像視圖, 這些資源變量通過描述符和描述符集佈局進行管理。 在管線內,管線佈局管理一系列的描述符集佈局。

2.pipeline的實現

爲了增加管線對象的可重用性,使用PCO提供管線緩存機制,減少創建類似管線的開銷。管線的實現必須放置在繪製對象可以輕鬆訪問 PCO 的集中位置,以提高管線可重用性。 爲此,有兩種選擇:將 VulkanPipeline 類放置在 VulkanApplication 內(在應用程序級別,這可能是主線程)或 VulkanRenderer 內(用於每個獨立的渲染線程)。 只要應用程序能夠通過正確處理內存泄漏和線程同步合理地管理管線對象,那麼這兩個選項使用哪個都可以。不過, 將 VulkanPipeline 放置在 VulkanRenderer 中以避免線程的同步,使其對初學者來說更簡單一些。

該視圖表示應用程序系統與用戶定義的 VulkanPipeline 類的集成:

使用 PCO 緩存管線對象 pipeline objects

管線緩存是一個用於存儲管線的池, 它使應用程序能夠減少管線運行之間以及後續應用程序運行之間的管線創建開銷。 以下是兩者之間的區別:

  • 管線 pipelines 之間:當新的管線被創建時,管線構造是可以重用的。 管線緩存對象作爲參數傳遞給管線創建器 API(vkCreateGraphicsPipelines)。 通過這樣做,底層的機制可確保在存在類似的管線時能夠對其進行重用。 這在創建本質上是冗餘的繪圖對象時非常有用,例如繪畫畫筆,精靈,網格幾何體等等。
  • 在應用程序 applications 之間:在創建管線時,會處理大量的管線狀態對象,這是一種昂貴的操作。 在正在運行的應用程序中重用是一個明智的設計,並且在執行時間和內存空間方面非常高效。 Vulkan 應用程序中的管線緩存可以通過序列化管線緩存對象來有效地進行重用。 應用程序從序列化的管線緩存中檢索存儲的管線對象並對其進行預初始化。 在後續運行中,可以在多個應用程序運行中重複使用相同的序列化 PCO。

2.1創建管線緩存對象 pipeline cache object

PCO 可用於創建圖形管線(vkCreateGraphicsPipelines)或計算管線(vkCreateComputePipelines)。 使用 PCO 創建這些管線可確保管線對象的可重用性。 如果 PCO 不包含類似的管線,則會創建一個新的管線並將其添加到它的池中。

可以使用 vkCreatePipelineCache()API 創建 PCO。 在成功創建後,會返回一個 VkPipelineCache 對象。

VkResult vkCreatePipelineCache(
VkDevice    device,
const VkPipelineCacheCreateInfo*    pCreateInfo, 
const VkAllocationCallbacks*   pAllocator, 
VkPipelineCache*        pPipelineCache);

 2.2從管線緩存 pipeline caches 檢索數據

管線緩存對象可以以字節流的形式保存其信息。 當應用程序重新運行或再次執行時,這些存儲的信息可以在以後重用。 管線緩存數據可以使用 vkGetPipelineCacheData()API 檢索:

VkResult vkGetPipelineCacheData(
VkDevice    device,
VkPipelineCache pipelineCache,
size_t* dataSize,
void*   data);

 

3.創建圖形管線 graphics pipeline

圖形管線由可編程的固定功能管線階段渲染通道子通道以及管線佈局組成。 可編程階段包括多個着色器階段,例如頂點着色器、片段着色器、表面細分着色器、幾何着色器和計算着色器。 固定功能的狀態由多個管線狀態對象 pipeline state objects (PSO)組成,這些對象表示動態的信息:頂點輸入,輸入的裝配,光柵化,混合,視口,多重採樣和深度模板狀態。

使用 vkCreateGraphicsPipelines()API 創建圖形管線對象(VkPipeline)。 該 API 會通過名爲 VkGraphicsPipelineCreateInfo 的元數據控制結構影響可編程階段,固定功能管線階段和管線佈局。

3.1.實現圖形管線 graphics pipeline

圖形管線在 VulkanPipeline 的 createPipeline()函數中實現。 該函數需要四個參數。 第一個參數包含頂點輸入和數據解析。 第二個參數包含返回值,會在其中創建管線數組。 第三個參數是一個表示深度測試的布爾標誌。 最後一個參數用於指定是否考慮頂點輸入。

圖形管線由幾個管線狀態對象,渲染通道,着色器對象和子通道組成,如下圖所示。 通過創建 VkGraphicsPipelineCreateInfo 對象(pipelineInfo)並在其中指定所有的各種狀態對象,着色器對象以及渲染通道對象來完成管線的實現。 最後,vkCreateGraphicsPipelines()API 使用管線對象創建管線。 下圖顯示了圖形管線及其所有的接口控制器:

4.計算管線 compute pipelines

計算管線由一個靜態的計算着色器階段管線佈局組成。 計算着色器階段能夠任意進行大規模並行計算。 另一方面,管線佈局使用佈局綁定將計算管線連接到描述符。 vkCreateComputePipeline()API 可用於創建計算管線:

VkResult vkCreateComputePipelines(
VkDevice  device,
VkPipelineCache pipelineCache,
uint32_t  createInfoCount,
const VkComputePipelineCreateInfo*  pCreateInfos, 
const VkAllocationCallbacks*    pAllocator, 
VkPipeline*     pPipelines);

5.Vulkan 中的管線狀態對象 Pipeline State Objects-PSO

管線中的管線狀態對象是控制物理設備硬件設置的一種手段。 管線中指定了各種類型的管線狀態對象;以預定義的順序進行工作。 這些階段中的輸入數據和資源會根據用戶指定的行爲進行更改。 每個階段都會處理輸入並將其傳遞給下一個輸入。 根據應用程序的要求,管線狀態階段可以根據用戶的選擇繞過。 這完全可以通過 VkComputePipelineCreateInfo 進行配置。

在我們詳細介紹這些管線狀態對象之前,先讓我們對它們進行一個簡單的概述:

  • 動態狀態:dynamic state, 它指定了在此管線中使用的動態狀態。
  • 頂點輸入狀態:vertex input state, 這指定了數據輸入速率及其解釋。
  • 輸入裝配狀態:input assembly state, 這個把頂點數據組裝成圖元的拓撲(線,點和三角形變體)。
  • 光柵化狀態:rasterization state, 此操作與光柵化相關,如多邊形填充模式,正面信息,剔除模式信息等。
  • 顏色混合狀態:color blend state, 這指定源片段和目標片段之間的混合因子和操作。
  • 視口狀態:viewport state, 它定義了視口,裁剪器和尺寸。
  • 深度 / 模板狀態:depth/stencil state, 這指定了如何執行深度 / 模板操作。
  • 多重採樣狀態:multisampling state, 這個控制着柵格化期間用於抗鋸齒目的的像素描繪中使用的採樣。

以下圖表說明了 PSO 中的每個階段:

光柵化 Rasterization

片段是在光柵化階段使用基本的拓撲結構生成的。 光柵化的圖像由稱爲片段的小方塊組成,以網格方式排列。片段是幀緩衝區中(x,y)位置的邏輯組合,對應於深度(z)以及片段着色器添加的相關數據和屬性。

每個圖元都要經過光柵化過程,並根據拓撲形狀確定相應的片段。 在此,計算每個圖元的整數位置,從而產生幀緩衝區網格上對應的點或方塊。 與位置一起,負責確定最終片段顏色的一個或多個深度值及其屬性會被存儲在幀緩衝區中。 每個計算點可以有一個或多個深度值;這表明存在多個重疊的圖元(完全或部分)競爭相同的位置。 然後根據深度和相關屬性信息解析這些片段。

片段可能是非方形的,這並不影響光柵化過程的工作方式。 柵格化與片段的高寬比無關。 由於正方形簡化了抗鋸齒和紋理化的過程,因此將片段假定爲正方形。

最終計算出的片段是一個對應於幀緩衝區的像素。 任何屬於幀緩衝區維度以外的片段都會被丟棄,並且在管線後期階段不再考慮,包括任何早期的逐片段測試。 片段着色器處理倖存的片段,並修改現有的深度值以及與片段相關聯的數據。

多重採樣

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章