Baiklah, saya mengalami kesulitan mendapatkan bool dikemas dan disejajarkan ke buffer hlsl konstan dan saya tidak yakin mengapa.
Berikut adalah buffer di hlsl
cbuffer MaterialBuffer : register(b1) {
float3 materialDiffuseAlbedo;
float materialSpecularExponent;
float3 materialSpecularAlbedo;
bool isTextured;
};
Dan ini dia di c ++
struct GeometryBufferPass_MaterialBuffer {
XMFLOAT3 diffuse;
float specularExponent;
XMFLOAT3 specular;
bool isTextured;
};
Saya sudah mencoba memindahkan bool dan mengisi struct dengan segala macam cara tanpa hasil. Apa cara yang benar untuk melakukan ini?
directx
hlsl
data-structure
KlashnikovKid
sumber
sumber
Jawaban:
Untuk efisiensi, buffer konstan akan dipetakan sedemikian sehingga nilai-nilai tidak mengangkangi register GPU . Setiap register berukuran empat float (16 byte) sehingga struktur penyangga konstan harus merupakan kelipatannya pada GPU. Struktur C ++ Anda harus diisi sesuai jika Anda ingin menggunakannya sebagai kenyamanan untuk memetakan data (ini, perhatikan, tidak selalu skala dengan baik).
Masalah Anda, kemudian, adalah bahwa boolean HLSL adalah empat byte, tetapi satu byte di sisi CPU (dalam implementasi spesifik Anda). Ini menyebabkan struktur C ++ Anda tidak sejajar dengan benar: bit signifikan dari nilai boolean (0 atau 1 yang penting) akan disimpan dalam byte nilai yang paling tidak signifikan, dan karena ukurannya tidak sesuai dengan lokasi byte itu dalam memori akan berbeda dalam versi CPU dan GPU struktur.
Secara manual memasukkan padding yang sesuai dan memastikan keselarasan 16 byte yang tepat, atau hanya menggunakan jenis berukuran tepat, seperti integer, harus memperbaiki masalah. Utas ini juga dapat bermanfaat bagi Anda karena berisi diskusi yang lebih mendalam tentang masalah yang kira-kira sama.
sumber
isTextured
masuk ke dalam register yang sama karena harus mengangkang ke yang berikutnya. Dengan demikian ia sepenuhnya masuk ke register berikutnya." Register kedua terdiri darispecular
tiga komponen pertama danisTextured
yang terakhir, jadi saya tidak melihat ada yang perlu ditabrak ke register berikutnya? Panjang bool 1-byte vs 4-byte jelas penting, tetapi salah satu akan cocok setelahspecular
dalam register yang sama.Baiklah, saya membaca dan memperhatikan bahwa hlsl bool pada dasarnya adalah integer 32 bit. Jadi saya hanya menggunakan int di c ++ struct untuk menyelesaikan masalah saya.
sumber
float, bool dan int tidak perlu berbaris untuk endian terutama untuk beberapa item.
Beralih ke int atau float berfungsi dalam beberapa contoh yang tercantum di sini sebagai yang disejajarkan antara item XMFLOAT3 sehingga dirujuk dengan benar. Namun jika Anda perlu mendeklarasikan array atau beberapa item dalam struktur untuk int, float (tidak ada tipe XM) maka Anda mungkin akan menemukan bahwa nilai GPU tidak cocok dengan nilai yang diatur dalam struktur CPU.
Tentu saya lakukan ketika menambahkan array tipe int untuk digunakan untuk jenis pencahayaan.
Cara termudah yang saya temukan adalah menempel pada tipe XM yang sejajar dengan 16, yang mungkin memerlukan elemen / byte yang terbuang tetapi mengurutkan endian untuk Anda. EG XMINT4 dan baru saja menggunakan elemen pertama .x untuk nilai Anda, atau jika Anda membutuhkannya, gunakan elemen-elemen lain untuk tujuan lain tetapi artinya penamaan yang buruk (pastikan untuk berkomentar). Catatan: array XMINT2 juga akan keluar dari urutan logis
sumber