Bagikan melalui


Mengkloning Efek

Mengkloning efek menciptakan salinan efek yang kedua dan hampir identik. Lihat kualifikasi tunggal berikut untuk penjelasan mengapa itu tidak tepat. Salinan kedua efek berguna ketika seseorang ingin menggunakan kerangka kerja efek pada beberapa utas, karena runtime efek tidak aman untuk mempertahankan performa tinggi.

Karena konteks perangkat juga tidak aman, utas yang berbeda harus meneruskan konteks perangkat yang berbeda ke metode ID3DX11EffectPass::Apply.

Efek dapat dikloning dengan sintaks berikut:

ID3DX11Effect* pClonedEffect = NULL;
UINT Flags = D3DX11_EFFECT_CLONE_FORCE_NONSINGLE;
HRESULT hr = pEffect->CloneEffect( Flags, &pClonedEffect );

Dalam contoh di atas, salinan kloning akan merangkum status yang sama dengan efek asli, terlepas dari status apa efek aslinya. Secara khusus:

  1. Jika pEffect dioptimalkan, Efek pCloned dioptimalkan
  2. Jika pEffect memiliki beberapa variabel yang dikelola pengguna, Efek pCloned akan memiliki variabel yang dikelola pengguna yang sama (lihat deskripsi tunggal di bawah)
  3. Setiap pembaruan variabel yang tertunda (hingga status perangkat Terapkan pembaruan panggilan) di pEffect akan tertunda di pClonedEffect

Objek perangkat Direct3D 11 berikut tidak dapat diubah atau tidak pernah diperbarui oleh kerangka kerja efek, sehingga efek kloning akan menunjuk ke objek yang sama dengan efek aslinya:

  1. Objek blok status (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
  2. Efek gambar
  3. Instans kelas
  4. Tekstur (tidak termasuk buffer tekstur)
  5. Tampilan akses yang tidak diurutkan

Objek perangkat Direct3D 11 berikut tidak dapat diubah dan dimodifikasi oleh runtime efek (kecuali dikelola pengguna atau tunggal dalam efek kloning); salinan baru objek ini dibuat saat tidak tunggal:

  1. Buffer konstanta
  2. Buffer Tekstur

Buffer Konstanta Tunggal dan Buffer Tekstur

Perhatikan bahwa diskusi ini berlaku untuk buffer dan tekstur konstanta, tetapi buffer konstan diasumsikan untuk kemudahan membaca.

Mungkin ada kasus di mana buffer konstanta hanya diperbarui oleh satu utas, tetapi status perangkat yang diatur oleh efek kloning akan menggunakan data ini. Misalnya, efek utama dapat memperbarui dunia dan melihat matriks yang direferensikan dari shader dalam efek kloning yang tidak mengubah dunia dan melihat matriks. Dalam kasus ini, efek kloning perlu mereferensikan buffer konstanta saat ini alih-alih membuatnya kembali.

Ada dua cara untuk mencapai hasil yang diinginkan ini:

  1. Gunakan ID3DX11EffectConstantBuffer::SetConstantBuffer pada efek kloning untuk membuatnya dikelola pengguna
  2. Tandai buffer konstanta sebagai "tunggal" dalam kode HLSL, memaksa runtime efek untuk diperlakukan adalah sebagai dikelola pengguna setelah kloning

Ada dua perbedaan antara dua metode di atas. Pertama, dalam metode 1, ID3D11Buffer baru akan dibuat dan pengguna sebelum SetConstantBuffer dipanggil. Selain itu, setelah memanggil UndoSetConstantBuffer dalam efek kloning, variabel dalam metode 1akan menunjuk ke buffer yang baru dibuat (efek mana yang akan diperbarui pada Terapkan) sementara variabel dalam metode 2 akan terus menunjuk ke buffer asli (tidak memperbaruinya saat Diterapkan).

Lihat contoh berikut di HLSL:

cbuffer ObjectData
{
    float4 Position;
};
single cbuffer ViewData
{
    float4x4 ViewMatrix;
};

Saat mengkloning, efek kloning akan membuat ID3D11Buffer baru untuk ObjectData, dan mengisi kontennya pada Terapkan, tetapi mereferensikan ID3D11Buffer asli untuk ViewData. Kualifikasi tunggal dapat diabaikan dalam proses kloning dengan mengatur bendera D3DX11_EFFECT_CLONE_FORCE_NONSINGLE.

Efek (Direct3D 11)