Menentukan Tanda Tangan Akar di HLSL
Menentukan tanda tangan akar dalam HLSL Shader Model 5.1 adalah alternatif untuk menentukannya dalam kode C++.
- Contoh Tanda Tangan Akar HLSL
- RootFlags
- Konstanta Akar
- Visibilitas
- CBV tingkat akar
- SRV tingkat akar
- UAV tingkat akar
- Tabel Deskriptor
- Sampler Statis
- Mengkompilasi tanda tangan akar HLSL
- Memanipulasi tanda tangan akar dengan pengkompilasi FXC
- Catatan
- Topik terkait
Contoh Tanda Tangan Akar HLSL
Tanda tangan akar dapat ditentukan dalam HLSL sebagai string. String berisi kumpulan klausa yang dipisahkan koma yang menjelaskan komponen konstituen tanda tangan akar. Tanda tangan akar harus identik di seluruh shader untuk satu objek status alur (PSO). Ini contohnya:
Tanda Tangan Akar Versi 1.0
#define MyRS1 "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \
"DENY_VERTEX_SHADER_ROOT_ACCESS), " \
"CBV(b0, space = 1), " \
"SRV(t0), " \
"UAV(u0, visibility = SHADER_VISIBILITY_GEOMETRY), " \
"DescriptorTable( CBV(b0), " \
"UAV(u1, numDescriptors = 2), " \
"SRV(t1, numDescriptors = unbounded)), " \
"DescriptorTable(Sampler(s0, numDescriptors = 2)), " \
"RootConstants(num32BitConstants=1, b9), " \
"DescriptorTable( UAV(u3), " \
"UAV(u4), " \
"UAV(u5, offset=1)), " \
"StaticSampler(s2)," \
"StaticSampler(s3, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"filter = FILTER_MIN_MAG_MIP_LINEAR )"
Definisi ini akan memberikan tanda tangan akar berikut, mencatat:
- Penggunaan parameter default.
- b0 dan (b0, spasi=1) tidak berkonflik
- u0 hanya terlihat oleh shader geometri
- u4 dan u5 dialirkan ke deskriptor yang sama dalam tumpukkan
Tanda Tangan Akar Versi 1.1
Root Signature Versi 1.1 memungkinkan pengoptimalan driver pada deskriptor dan data tanda tangan akar.
#define MyRS1 "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \
"DENY_VERTEX_SHADER_ROOT_ACCESS), " \
"CBV(b0, space = 1, flags = DATA_STATIC), " \
"SRV(t0), " \
"UAV(u0), " \
"DescriptorTable( CBV(b1), " \
"SRV(t1, numDescriptors = 8, " \
" flags = DESCRIPTORS_VOLATILE), " \
"UAV(u1, numDescriptors = unbounded, " \
" flags = DESCRIPTORS_VOLATILE)), " \
"DescriptorTable(Sampler(s0, space=1, numDescriptors = 4)), " \
"RootConstants(num32BitConstants=3, b10), " \
"StaticSampler(s1)," \
"StaticSampler(s2, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"filter = FILTER_MIN_MAG_MIP_LINEAR )"
Bahasa tanda tangan akar HLSL sangat sesuai dengan API tanda tangan akar C++ dan memiliki daya ekspresif yang setara. Tanda tangan akar ditentukan sebagai urutan klausa, dipisahkan oleh koma. Urutan klausa penting, karena urutan penguraian menentukan posisi slot dalam tanda tangan akar. Setiap klausa mengambil satu atau beberapa parameter bernama. Namun, urutan parameter tidak penting.
RootFlags
Klausa RootFlags opsional mengambil 0 (nilai default untuk menunjukkan tidak ada bendera), atau satu atau beberapa nilai bendera akar yang telah ditentukan sebelumnya, tersambung melalui operator OR '|'. Nilai bendera akar yang diizinkan ditentukan oleh D3D12_ROOT_SIGNATURE_FLAGS.
Contohnya:
RootFlags(0) // default value – no flags
RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT)
RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | DENY_VERTEX_SHADER_ROOT_ACCESS)
Konstanta Akar
Klausa RootConstants menentukan konstanta akar dalam tanda tangan akar. Dua parameter wajib adalah: num32BitConstants dan bReg (register yang sesuai dengan BaseShaderRegister di C++ API) dari cbuffer. Spasi (RegisterSpace di C++ API) dan parameter visibilitas (ShaderVisibility in C++) bersifat opsional, dan nilai defaultnya adalah:
RootConstants(num32BitConstants=N, bReg [, space=0,
visibility=SHADER_VISIBILITY_ALL ])
Contohnya:
RootConstants(num32BitConstants=3, b3)
Visibilitas
Visibilitas adalah parameter opsional yang dapat memiliki salah satu nilai dari D3D12_SHADER_VISIBILITY.
SHADER_VISIBILITY_ALL menyiarkan argumen akar ke semua shader. Pada beberapa perangkat keras ini tidak memiliki biaya, tetapi pada perangkat keras lain ada biaya untuk fork data ke semua tahap shader. Mengatur salah satu opsi, seperti SHADER_VISIBILITY_VERTEX, membatasi argumen akar ke satu tahap shader.
Mengatur argumen akar ke tahap shader tunggal memungkinkan nama ikat yang sama digunakan pada tahap yang berbeda. Misalnya, pengikatan t0,SHADER_VISIBILITY_VERTEX
SRV dan pengikatan t0,SHADER_VISIBILITY_PIXEL
SRV akan valid. Tetapi jika pengaturan visibilitas adalah t0,SHADER_VISIBILITY_ALL
untuk salah satu pengikatan, tanda tangan akar akan tidak valid.
CBV tingkat akar
CBV
Klausa (tampilan buffer konstanta) menentukan entri Reg buffer konstanta tingkat akar b-register. Perhatikan bahwa ini adalah entri skalar; tidak dimungkinkan untuk menentukan rentang untuk tingkat akar.
CBV(bReg [, space=0, visibility=SHADER_VISIBILITY_ALL ]) // Version 1.0
CBV(bReg [, space=0, visibility=SHADER_VISIBILITY_ALL, // Version 1.1
flags=DATA_STATIC_WHILE_SET_AT_EXECUTE ])
SRV tingkat akar
SRV
Klausa (tampilan sumber daya shader) menentukan entri Reg t-register SRV tingkat akar. Perhatikan bahwa ini adalah entri skalar; tidak dimungkinkan untuk menentukan rentang untuk tingkat akar.
SRV(tReg [, space=0, visibility=SHADER_VISIBILITY_ALL ]) // Version 1.0
SRV(tReg [, space=0, visibility=SHADER_VISIBILITY_ALL, // Version 1.1
flags=DATA_STATIC_WHILE_SET_AT_EXECUTE ])
UAV tingkat akar
UAV
Klausa (tampilan akses tidak berurut) menentukan entri Reg u-register UAV tingkat akar. Perhatikan bahwa ini adalah entri skalar; tidak dimungkinkan untuk menentukan rentang untuk tingkat akar.
UAV(uReg [, space=0, visibility=SHADER_VISIBILITY_ALL ]) // Version 1.0
UAV(uReg [, space=0, visibility=SHADER_VISIBILITY_ALL, // Version 1.1
flags=DATA_VOLATILE ])
Contohnya:
UAV(u3)
Tabel Deskriptor
Klausa DescriptorTable
itu sendiri adalah daftar klausul tabel deskriptor yang dipisahkan koma, serta parameter visibilitas opsional. Klausa DescriptorTable mencakup CBV, SRV, UAV, dan Sampler. Perhatikan bahwa parameternya berbeda dari klausul tingkat akar.
DescriptorTable( DTClause1, [ DTClause2, … DTClauseN,
visibility=SHADER_VISIBILITY_ALL ] )
Tabel CBV
Deskriptor memiliki sintaks berikut:
CBV(bReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND ]) // Version 1.0
CBV(bReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND // Version 1.1
, flags=DATA_STATIC_WHILE_SET_AT_EXECUTE ])
Contohnya:
DescriptorTable(CBV(b0),SRV(t3, numDescriptors=unbounded))
Parameter wajib bReg menentukan Reg mulai dari rentang cbuffer. Parameter numDescriptors menentukan jumlah deskriptor dalam rentang cbuffer yang berdekatan; nilai defaultnya adalah 1. Entri mendeklarasikan rentang [Reg, Reg + numDescriptors - 1]
cbuffer, ketika numDescriptors adalah angka. Jika numDescriptors sama dengan "tidak terikat", rentangnya adalah [Reg, UINT_MAX]
, yang berarti aplikasi harus memastikannya tidak mereferensikan area di luar batas. Bidang offset mewakili parameter OffsetInDescriptorsFromTableStart di API C++, yaitu offset (dalam deskriptor) dari awal tabel. Jika offset diatur ke DESCRIPTOR_RANGE_OFFSET_APPEND (default), itu berarti rentangnya langsung setelah rentang sebelumnya. Namun, memasukkan offset tertentu memang memungkinkan rentang saling tumpang tindih, memungkinkan alias pendaftaran.
Tabel SRV
Deskriptor memiliki sintaks berikut:
SRV(tReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND ]) // Version 1.0
SRV(tReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND, // Version 1.1
flags=DATA_STATIC_WHILE_SET_AT_EXECUTE ])
Ini mirip dengan entri tabel CBV
deskriptor, kecuali rentang yang ditentukan adalah untuk tampilan sumber daya shader.
Tabel UAV
Deskriptor memiliki sintaks berikut:
UAV(uReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND ]) // Version 1.0
UAV(uReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND, // Version 1.1
flags=DATA_VOLATILE ])
Ini mirip dengan entri tabel CBV
deskriptor, kecuali rentang yang ditentukan adalah untuk tampilan akses yang tidak diurutkan.
Tabel Sampler
Deskriptor memiliki sintaks berikut:
Sampler(sReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND ]) // Version 1.0
Sampler(sReg [, numDescriptors=1, space=0, offset=DESCRIPTOR_RANGE_OFFSET_APPEND, // Version 1.1
flags=0 ])
Ini mirip dengan entri tabel CBV
deskriptor, kecuali rentang yang ditentukan adalah untuk sampel shader. Perhatikan bahwa Sampler tidak dapat dicampur dengan jenis deskriptor lain dalam tabel deskriptor yang sama (karena berada dalam tumpukan deskriptor terpisah).
Sampler Statis
Sampler statis mewakili struktur D3D12_STATIC_SAMPLER_DESC . Parameter wajib untuk StaticSampler adalah Reg skalar dan sampler s-register. Parameter lain bersifat opsional dengan nilai default yang ditunjukkan di bawah ini. Sebagian besar bidang menerima sekumpulan enum yang telah ditentukan sebelumnya.
StaticSampler( sReg,
[ filter = FILTER_ANISOTROPIC,
addressU = TEXTURE_ADDRESS_WRAP,
addressV = TEXTURE_ADDRESS_WRAP,
addressW = TEXTURE_ADDRESS_WRAP,
mipLODBias = 0.f,
maxAnisotropy = 16,
comparisonFunc = COMPARISON_LESS_EQUAL,
borderColor = STATIC_BORDER_COLOR_OPAQUE_WHITE,
minLOD = 0.f,
maxLOD = 3.402823466e+38f,
space = 0,
visibility = SHADER_VISIBILITY_ALL ])
Contohnya:
StaticSampler(s4, filter=FILTER_MIN_MAG_MIP_LINEAR)
Opsi parameter sangat mirip dengan panggilan API C++, kecuali borderColor, yang dibatasi untuk enum di HLSL.
Bidang filter bisa menjadi salah satu D3D12_FILTER.
Bidang alamat masing-masing bisa menjadi salah satu D3D12_TEXTURE_ADDRESS_MODE.
Fungsi perbandingan bisa menjadi salah satu D3D12_COMPARISON_FUNC.
Bidang warna batas bisa menjadi salah satu D3D12_STATIC_BORDER_COLOR.
Visibilitas bisa menjadi salah satu D3D12_SHADER_VISIBILITY.
Mengkompilasi tanda tangan akar HLSL
Ada dua mekanisme untuk mengkompilasi tanda tangan akar HLSL. Pertama, dimungkinkan untuk melampirkan string tanda tangan akar ke shader tertentu melalui atribut RootSignature (dalam contoh berikut, menggunakan titik entri MyRS1 ):
[RootSignature(MyRS1)]
float4 main(float4 coord : COORD) : SV_Target
{
…
}
Pengkompilasi akan membuat dan memverifikasi blob tanda tangan akar untuk shader dan menyematkannya bersama kode byte shader ke dalam blob shader. Pengkompilasi mendukung sintaks tanda tangan akar untuk model shader 5.0 dan yang lebih tinggi. Jika tanda tangan akar disematkan dalam shader model shader 5.0 dan shader tersebut dikirim ke runtime D3D11, dibandingkan dengan D3D12, bagian tanda tangan akar akan diabaikan secara diam-diam oleh D3D11.
Mekanisme lainnya adalah membuat blob tanda tangan akar mandiri, mungkin untuk menggunakannya kembali dengan seperangkat shader yang besar, menghemat ruang. Effect-Compiler Tool (FXC) mendukung model shader rootsig_1_0 danrootsig_1_1. Nama string definisi ditentukan melalui argumen /E biasa. Contohnya:
fxc.exe /T rootsig_1_1 MyRS1.hlsl /E MyRS1 /Fo MyRS1.fxo
Perhatikan bahwa string tanda tangan akar juga dapat diteruskan pada baris perintah, misalnya, /D MyRS1="...".
Memanipulasi tanda tangan akar dengan pengkompilasi FXC
Pengkompilasi FXC membuat kode byte shader dari file sumber HLSL. Ada banyak parameter opsional untuk pengkompilasi ini, lihat Alat Pengkompilasi Efek.
Untuk mengelola tanda tangan akar yang ditulis HLSL, tabel berikut memberikan beberapa contoh penggunaan FXC.
Garis | Baris perintah | Deskripsi |
---|---|---|
1 | fxc /T ps_5_1 shaderWithRootSig.hlsl /Fo rs1.fxo |
Mengkompilasi shader untuk target pixel shader 5.1, sumber shader berada di file shaderWithRootSig.hlsl, yang menyertakan tanda tangan root. Shader dan tanda tangan akar dikompilasi sebagai blob terpisah dalam file biner rs1.fxo. |
2 | fxc /dumpbin rs1.fxo /extractrootsignature /Fo rs1.rs.fxo |
Mengekstrak tanda tangan akar dari file yang dibuat oleh baris 1, sehingga file rs1.rs.fxo hanya berisi tanda tangan akar. |
3 | fxc /dumpbin rs1.fxo /Qstrip_rootsignature /Fo rs1.stripped.fxo |
Menghapus tanda tangan akar dari file yang dibuat oleh baris 1, sehingga file rs1.stripped.fxo berisi shader tanpa tanda tangan root. |
4 | fxc /dumpbin rs1.stripped.fxo /setrootsignature rs1.rs.fxo /Fo rs1.new.fxo |
Menggabungkan shader dan tanda tangan akar yang berada dalam file terpisah ke dalam file biner yang berisi kedua blob. Dalam contoh ini rs1.new.fx0 akan identik dengan rs1.fx0 di baris 1. |
5 | fxc /T rootsig_1_0 rootSigAndMaybeShaderInHereToo.hlsl /E RS1 /Fo rs2.fxo |
Membuat file biner tanda tangan akar yang berdiri sendiri dari sumber yang mungkin berisi lebih dari sekadar tanda tangan akar. Perhatikan target rootsig_1_0, dan bahwa RS1 adalah nama string makro tanda tangan akar (#define) dalam file HLSL. |
Fungsionalitas yang tersedia melalui FXC juga tersedia secara terprogram menggunakan fungsi D3DCompile . Panggilan ini mengkompilasi shader dengan tanda tangan akar, atau tanda tangan akar yang berdiri sendiri (mengatur target rootsig_1_0). D3DGetBlobPart dan D3DSetBlobPart dapat mengekstrak dan melampirkan tanda tangan root ke blob yang ada. D3D_BLOB_ROOT_SIGNATURE digunakan untuk menentukan jenis bagian blob tanda tangan akar. D3DStripShader menghapus tanda tangan akar (menggunakan bendera D3DCOMPILER_STRIP_ROOT_SIGNATURE) dari blob.
Catatan
Catatan
Sedangkan kompilasi offline shader sangat disarankan, jika shader harus dikompilasi saat runtime, lihat keterangan untuk D3DCompile2.
Catatan
Aset HLSL yang ada tidak perlu diubah untuk menangani tanda tangan akar untuk digunakan bersamanya.
Topik terkait