間接繪圖

間接繪圖可讓一些場景周遊和消除從 CPU 移至 GPU,進而改善效能。 命令緩衝區可由 CPU 或 GPU 產生。

命令簽章

命令簽章物件 (ID3D12CommandSignature) 可讓應用程式指定間接繪圖,特別是下列設定:

啟動時,應用程式會建立一組小型 的命令簽章。 在執行時間,應用程式會透過應用程式開發人員選擇) 的方式,使用命令 (填滿緩衝區。 命令選擇性地包含要針對頂點緩衝區檢視、索引緩衝區檢視、根常數和根描述元設定的狀態, (原始或結構化 SRV/UAV/CBV) 。 這些引數配置並非硬體專屬,因此應用程式可以直接產生緩衝區。 命令簽章會從命令清單中繼承其餘狀態。 然後,應用程式會呼叫 ExecuteIndirect ,指示 GPU 根據特定命令簽章所定義的格式來解譯間接引數緩衝區的內容。

如果命令簽章變更任何根引數,這會儲存在命令簽章中做為根簽章的子集。

請注意,當執行完成時,沒有命令簽章狀態流失回命令清單。

例如,假設應用程式開發人員想要在間接引數緩衝區中指定個別繪製呼叫的唯一根常數。 應用程式會建立命令簽章,讓間接引數緩衝區為每個繪製呼叫指定下列參數:

  • 一個根常數的值。
  • 繪製引數 (頂點計數、實例計數等) 。

應用程式所產生的間接引數緩衝區會包含固定大小記錄的陣列。 每個結構都會對應至一個繪製呼叫。 每個結構都包含繪圖引數,以及根常數的值。 繪製呼叫的數目是在個別的 GPU 可見緩衝區中指定。

應用程式所產生的範例命令緩衝區如下:

命令緩衝區格式

間接引數緩衝區結構

下列結構會定義特定引數在間接引數緩衝區中的顯示方式。 這些結構不會出現在任何 D3D12 API 中。 應用程式在寫入間接引數緩衝區時會使用這些定義, (CPU 或 GPU) :

建立命令簽章

若要建立命令簽章,請使用下列 API 專案:

間接引數緩衝區內的引數順序會定義為完全符合D3D12_COMMAND_SIGNATURE_DESCpArguments參數中指定的引數順序。 一個繪製 (圖形的所有引數,) /dispatch (間接引數緩衝區內的計算) 呼叫都會緊密封裝。 不過,允許應用程式在間接引數緩衝區中指定繪製/分派命令之間的任意位元組間距。

只有在命令簽章變更其中一個根引數時,才必須指定根簽章。

針對根 SRV/UAV/CBV,應用程式指定的大小是以位元組為單位。 偵錯層會驗證位址的下列限制:

  • CBV – 位址必須是 256 個位元組的倍數。
  • 原始 SRV/UAV – 位址必須是 4 個位元組的倍數。
  • 結構化 SRV/UAV – 位址必須是著色器) 中所宣告之結構位元組的倍數 (。

指定的命令簽章是繪製或計算命令簽章。 如果命令簽章包含繪圖作業,則它是圖形命令簽章。 否則,命令簽章必須包含分派作業,而且它是計算命令簽章。

下列各節顯示一些範例命令簽章。

無引數變更

在此範例中,應用程式所產生的間接引數緩衝區會保存 36 位元組結構的陣列。 每個結構只包含傳遞至 DrawIndexedInstanced (加上填補) 的五個參數。

建立命令簽章描述的程式碼如下:

D3D12_INDIRECT_ARGUMENT_DESC Args[1];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;

D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 36;
ProgramDesc.NumArgumentDescs = 1;
ProgramDesc.pArguments = Args;

間接引數緩衝區內單一結構的版面配置如下:

位元組 描述
0:3 IndexCountPerInstance
4:7 InstanceCount
8:11 StartIndexLocation
12:15 BaseVertexLocation
16:19 StartInstanceLocation
20:35 填補

 

根常數和頂點緩衝區

在此範例中,間接引數緩衝區中的每個結構都會變更兩個根常數、變更一個頂點緩衝區系結,並執行一個繪製非索引作業。 結構之間沒有邊框間距。

建立命令簽章描述的程式碼如下:

D3D12_INDIRECT_ARGUMENT_DESC Args[4];
Args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[0].Constant.RootParameterIndex = 2;
Args[0].Constant.DestOffsetIn32BitValues = 0;
Args[0].Constant.Num32BitValuesToSet = 1;

Args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
Args[1].Constant.RootParameterIndex = 6;
Args[1].Constant.DestOffsetIn32BitValues = 0;
Args[1].Constant.Num32BitValuesToSet = 1;

Args[2].Type = D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW;
Args[2].VertexBuffer.Slot = 3;

Args[3].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;

D3D12_COMMAND_SIGNATURE_DESC ProgramDesc;
ProgramDesc.ByteStride = 40;
ProgramDesc.NumArgumentDescs = 4;
ProgramDesc.pArguments = Args;

間接引數緩衝區內單一結構的版面配置如下:

位元組 描述
0:3 根參數索引 2 的資料
4:7 根參數索引 6 的資料
8:15 位置 3 (64 位) VB 的虛擬位址
16:19 VB 大小
20:23 VB 步進
24:27 VertexCountPerInstance
28:31 InstanceCount
32:35 StartVertexLocation
36:39 StartInstanceLocation

 

DirectX 進階學習影片教學課程:執行間接和非同步 GPU 擷取

間接繪圖和 GPU 擷取:程式碼逐步解說

轉譯