Gambar Tidak Langsung
Gambar tidak langsung memungkinkan beberapa scene-traversal dan culling dipindahkan dari CPU ke GPU, yang dapat meningkatkan performa. Buffer perintah dapat dihasilkan oleh CPU atau GPU.
- Tanda Tangan Perintah
- Struktur Buffer Argumen Tidak Langsung
- Pembuatan Tanda Tangan Perintah
- Topik terkait
Tanda Tangan Perintah
Objek tanda tangan perintah (ID3D12CommandSignature) memungkinkan aplikasi menentukan gambar tidak langsung, khususnya pengaturan berikut:
- Format buffer argumen tidak langsung.
- Jenis perintah yang akan digunakan (dari metode ID3D12GraphicsCommandList DrawInstanced, DrawIndexedInstanced, atau Dispatch).
- Kumpulan pengikatan sumber daya yang akan mengubah panggilan per perintah versus set yang akan diwariskan.
Saat memulai, aplikasi membuat sekumpulan kecil tanda tangan perintah. Pada runtime, aplikasi mengisi buffer dengan perintah (melalui apa pun artinya yang dipilih pengembang aplikasi). Perintah yang secara opsional berisi status untuk diatur untuk tampilan buffer vertex, tampilan buffer indeks, konstanta akar, dan deskriptor akar (SRV/UAV/CBV mentah atau terstruktur). Tata letak argumen ini tidak spesifik untuk perangkat keras sehingga aplikasi dapat menghasilkan buffer secara langsung. Tanda tangan perintah mewarisi status yang tersisa dari daftar perintah. Kemudian aplikasi memanggil ExecuteIndirect untuk menginstruksikan GPU untuk menginterpretasikan konten buffer argumen tidak langsung sesuai dengan format yang ditentukan oleh tanda tangan perintah tertentu.
Jika tanda tangan perintah mengubah argumen akar apa pun, maka itu disimpan dalam tanda tangan perintah sebagai subset tanda tangan akar.
Tidak ada status tanda tangan perintah yang bocor kembali ke daftar perintah setelah eksekusi selesai. Tetapi, setelah ExecuteIndirect, semua pengikatan diatur ulang ke nilai yang diketahui. Secara khusus:
- Jika tanda tangan perintah mengikat buffer vertex ke slot tertentu, maka setelah ExecuteIndirect dipanggil, buffer vertex NULL terikat ke slot tersebut.
- Jika tanda tangan perintah mengikat buffer indeks, maka setelah ExecuteIndirect, buffer indeks NULL terikat.
- Jika tanda tangan perintah mengatur konstanta akar, maka setelah ExecuteIndirect dipanggil, nilai konstanta akar diatur ke 0.
- Jika tanda tangan perintah mengatur tampilan akar (CBV/SRV/UAV), maka setelah ExecuteIndirect dipanggil, tampilan akar diatur ke tampilan NULL.
Sebagai contoh penggunaan tanda tangan perintah: misalkan pengembang aplikasi ingin konstanta akar unik ditentukan per panggilan gambar di buffer argumen tidak langsung. Aplikasi akan membuat tanda tangan perintah yang memungkinkan buffer argumen tidak langsung menentukan parameter berikut per panggilan gambar:
- Nilai satu konstanta akar.
- Argumen gambar (jumlah puncak, jumlah instans, dll).
Buffer argumen tidak langsung yang dihasilkan oleh aplikasi akan berisi array rekaman ukuran tetap. Setiap struktur sesuai dengan satu panggilan gambar. Setiap struktur berisi argumen gambar, dan nilai konstanta akar. Jumlah panggilan gambar ditentukan dalam buffer yang terlihat GPU terpisah.
Contoh buffer perintah yang dihasilkan oleh aplikasi berikut:
Struktur Buffer Argumen Tidak Langsung
Struktur berikut menentukan bagaimana argumen tertentu muncul dalam buffer argumen tidak langsung. Struktur ini tidak muncul di API D3D12 apa pun. Aplikasi menggunakan definisi ini saat menulis ke buffer argumen tidak langsung (dengan CPU atau GPU):
- D3D12_DRAW_ARGUMENTS
- D3D12_DRAW_INDEXED_ARGUMENTS
- D3D12_DISPATCH_ARGUMENTS
- D3D12_VERTEX_BUFFER_VIEW
- D3D12_INDEX_BUFFER_VIEW
- D3D12_GPU_VIRTUAL_ADDRESS (sinonim typedef dari UINT64).
- D3D12_CONSTANT_BUFFER_VIEW
Pembuatan Tanda Tangan Perintah
Untuk membuat tanda tangan perintah, gunakan item API berikut:
- ID3D12Device::CreateCommandSignature (menghasilkan ID3D12CommandSignature)
- D3D12_INDIRECT_ARGUMENT_TYPE
- D3D12_INDIRECT_ARGUMENT_DESC
- D3D12_COMMAND_SIGNATURE_DESC
Pengurutan argumen dalam buffer argumen tidak langsung didefinisikan agar sama persis dengan urutan argumen yang ditentukan dalam parameter pArguments D3D12_COMMAND_SIGNATURE_DESC. Semua argumen untuk satu panggilan gambar (grafis)/pengiriman (komputasi) dalam buffer argumen tidak langsung dikemas dengan erat. Namun, aplikasi diizinkan untuk menentukan byte stride arbitrer antara perintah draw/dispatch dalam buffer argumen tidak langsung.
Tanda tangan akar harus ditentukan jika dan hanya jika tanda tangan perintah mengubah salah satu argumen akar.
Untuk root SRV/UAV/CBV, ukuran aplikasi yang ditentukan dalam byte. Lapisan debug akan memvalidasi batasan berikut pada alamat:
- CBV – alamat harus kelipatan 256 byte.
- SRV/UAV mentah – alamat harus kelipatan 4 byte.
- SRV/UAV terstruktur – alamat harus berupa kelipatan langkah byte struktur (dinyatakan dalam shader).
Tanda tangan perintah tertentu adalah gambar atau tanda tangan perintah komputasi. Jika tanda tangan perintah berisi operasi menggambar, maka itu adalah tanda tangan perintah grafis. Jika tidak, tanda tangan perintah harus berisi operasi pengiriman, dan ini adalah tanda tangan perintah komputasi.
Bagian berikut ini memperlihatkan beberapa contoh tanda tangan perintah.
Tidak Ada Perubahan Argumen
Dalam contoh ini, buffer argumen tidak langsung yang dihasilkan oleh aplikasi menyimpan array struktur 36 byte. Setiap struktur hanya berisi lima parameter yang diteruskan ke DrawIndexedInstanced (ditambah padding).
Kode untuk membuat deskripsi tanda tangan perintah mengikuti:
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;
Tata letak struktur tunggal dalam buffer argumen tidak langsung adalah:
Byte | Deskripsi |
---|---|
0:3 | IndexCountPerInstance |
4:7 | HitungInstans |
8:11 | StartIndexLocation |
12:15 | BaseVertexLocation |
16:19 | StartInstanceLocation |
20:35 | Padding |
Konstanta Akar dan Buffer Vertex
Dalam contoh ini, setiap struktur dalam buffer argumen tidak langsung mengubah dua konstanta akar, mengubah satu pengikatan buffer vertex, dan melakukan satu menggambar operasi yang tidak diindeks. Tidak ada padding antar struktur.
Kode untuk membuat deskripsi tanda tangan perintah adalah:
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;
Tata letak struktur tunggal dalam buffer argumen tidak langsung adalah sebagai berikut:
Byte | Deskripsi |
---|---|
0:3 | Data untuk indeks parameter akar 2 |
4:7 | Data untuk indeks parameter akar 6 |
8:15 | Alamat virtual VB di slot 3 (64-bit) |
16:19 | Ukuran VB |
20:23 | Stride VB |
24:27 | VertexCountPerInstance |
28:31 | HitungInstans |
32:35 | StartVertexLocation |
36:39 | StartInstanceLocation |
Topik terkait