天天看點

Vulkan規範:第八章 8.3 ~ 8.10

8.4. 着色器的輸入和輸出

資料通過 input 和 output修飾的變量傳入和傳出着色器。 在不同階段之間使用者自定義的輸入和輸出是通過比對

Location

修飾符來聯系起來的。 另外,可以使用 

BuiltIn

 修飾符來對執行環境中特殊函數提供資料或進行資料交換。

在很多場合下,同一個

BuiltIn

可以在多個着色器階段使用,含義相近。 

BuiltIn

修飾的變量的行為在下面小節中有記錄。

8.5. 頂點着色器

對每一個頂點和它相關的vertex attribute資料,都調用一次頂點着色器, 輸出一個頂點和相關的資料。 圖形管線必須包含一個頂點着色器,且頂點着色器階段始終都是圖形管線的第一個階段。

8.5.1. 頂點着色器的執行

在一個繪制指令中,對于一個頂點至少執行一次。 在執行期間,對着色器提供了頂點的索引和頂點本身資料。 在着色器内聲明的輸入變量通過Vulkan實作填充與調用關聯的頂點屬性值。

如果在一個繪制指令中同一個頂點出現多次(),且如果頂點着色總是産生相同的結果, Vulkan實作也許會重用該結果。

注意

頂點着色的結果什麼時候、是否被重用以及頂點着色器被執行多少次,都是依賴于Vulkan實作的。 當頂點着色器包含存儲或者原子操作時依然如此(參看 

vertexPipelineStoresAndAtomics

)。

8.6. 細分控制着色器

細分控制着色器是用來讀取應用程式提供的輸入圖元,并産生一個輸出圖元。 對于一個圖元及關聯的資料,調用一次細分控制着色器(在頂點着色器處理完一個圖元所有的頂點之後), 并每一個輸出圖元輸出一個控制點及關聯資料,也可以輸出附加的圖中繼資料。 按照

VkPipelineTessellationStateCreateInfo

patchControlPoints

成員來調整輸入圖元的頂點個數, 這是輸入組裝的一部分。 輸出圖元的大小由細分控制或細分求值着色器指定的

OpExecutionMode

OutputVertices

 控制, 至少在其中一個着色器中指定。 輸入、輸出圖元的大小必須大于0,不大于

VkPhysicalDeviceLimits

::

maxTessellationPatchSize

8.6.1. 細分控制着色器的執行

對于一個圖元内每一個 output 頂點都至少調用一次細分控制着色器。

細分控制着色器的輸入是由頂點着色器生成的。 每一次細分控制着色器調用可以讀取任何一個輸入的頂點的屬性和它關聯的資料。 對于一個給定圖元的多次着色器調用邏輯上并行執行,相對順序是未定義的。 然而,通過在一個圖元内同步着色器調用,

OpControlBarrier

 指令可以用來提供對執行順序的有限度的控制, 有效地把細分控制着色器執行劃分為多個周期。 如果一次調用在同一個周期内讀取被其他調用寫入的逐頂點或者逐圖元屬性, 或者兩個調用嘗試在一個周期内向一個圖元輸出寫入,細分控制着色器将讀取到未定義的值。

8.7. 細分求值着色器(Tessellation Evaluation Shaders)

細分求值着色器在控制點組成的輸入圖元和它關聯資料上進行操作,單個輸入重心坐标表示了在子圖元中調用的對象的相對位置, 輸入單個頂點和關聯資料。

8.7.1. 細分求值着色器的執行

對細分器生成的每一個頂點至少調用一次細分求值着色器。

8.8. 幾何着色器

幾何着色器在一個輸入圖元上一系列的頂點和它們關聯的資料上進行操作,輸入零個或者多個輸出圖元,和它們的頂點及輸出每個圖元 需要的關聯資料。

8.8.1. 幾何着色器的執行

對于細分階段産生的每一個圖元,幾何着色器至少被調用一次,或者沒有使用細分時primitive assembly 生成的每一個圖元都調用至少一次。 每一個輸入圖元調用幾何着色器的次數是由幾何着色器中

OpExecutionMode

Invocations

指定的每圖元幾何着色器調用次數 決定。 如果調用次數未指定,預設隻調用一次。

8.9. 片元着色器

片元着色器作為圖形管線栅格化的結果被調用。 每一次片元着色器調用都作用在一個片元和它關聯的資料上。 除了少數例外,片元着色器并不通路其他片元關聯的資料,和其他片元關聯的片元着色器的執行之間是孤立的。

8.9.1. 片元着色器的執行

對于栅格化産生的每個片元,一個片元着色器都被調用一次。 如果 Early Per-Fragment Tests導緻它沒有被覆寫到 ,一個片元着色器就不能被調用。 還有,如果第一個圖元栅格化生成的片元的輸出将會被同一個subpass中第二個圖元栅格化産生的片元所覆寫, 且該片元所對應的片元着色器沒有其他副作用,那麼第一個圖元中這個片元可能不需要執行片元着色器。

不同的片元着色器相對的執行順序是未定義的。

每一個像素對應的片元着色器調用次數由以下規則決定:

  • 如果開啟了逐采樣着色,每一個被覆寫的采樣點都被執行一次。
  • 否則,每一個片元都至少需要執行一次片元着色器,但是每一個覆寫到的采樣點無需執行多次。

關于片元着色器調用,除了上面強調的條件外,片元着色器也可被 helper invocation 産生。 一個 helper invocation是一次片元着色器調用,隻為了給非helper 片元着色器求導而産生的。 helper 調用所執行的存儲和原子操作不能給記憶體造成任何副作用,helper調用中原子指令傳回的值是為定義的。

8.9.2. 早期片元測試

Vulkan提供了顯式的控制,允許片元着色器開啟早期片元測試。如果片元着色器指定了

EarlyFragmentTests

OpExecutionMode

, 在Early Fragment Test Mode中描述過的逐片元測試發生在片元着色器執行之前。 否則,它們在片元着色器執行之後才被執行。

8.10. 計算着色器

可通過 

vkCmdDispatch

 和

vkCmdDispatchIndirect

 指令來調用計算着色器。 總的來說,它們在各着色器階段執行時與圖形管線的一部分對資源有類似的通路權限。

Compute workloads are formed from groups of work items called workgroups and processed by the compute shader in the current compute pipeline. A workgroup is a collection of shader invocations that execute the same shader, potentially in parallel. Compute shaders execute in global workgroups which are divided into a number of local workgroups with a size that can be set by assigning a value to the 

LocalSize

 execution mode or via an object decorated by the

WorkgroupSize

 decoration. An invocation within a local workgroup can share data with other members of the local workgroup through shared variables and issue memory and control flow barriers to synchronize with other members of the local workgroup.

繼續閱讀