Condividi tramite


Clonazione di un effetto

La clonazione di un effetto crea una seconda copia quasi identica dell'effetto. Per una spiegazione del motivo per cui non è esatta, vedere il qualificatore singolo seguente. Una seconda copia di un effetto è utile quando si vuole usare il framework degli effetti su più thread, poiché il runtime dell'effetto non è thread safe per mantenere prestazioni elevate.

Poiché i contesti del dispositivo sono anche non thread-safe, i diversi thread devono passare contesti di dispositivo diversi al metodo ID3DX11EffectPass::Apply.

Un effetto può essere clonato con la sintassi seguente:

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

Nell'esempio precedente, la copia clonata incapsulerà lo stesso stato dell'effetto originale, indipendentemente dallo stato in cui si trova l'effetto originale. In particolare:

  1. Se pEffect è ottimizzato, pCloned Effect è ottimizzato
  2. Se pEffect ha alcune variabili gestite dall'utente, pCloned Effect avrà le stesse variabili gestite dall'utente (vedere la singola descrizione seguente)
  3. Eventuali aggiornamenti delle variabili in sospeso (fino a quando non viene applicato lo stato del dispositivo Applica aggiornamenti delle chiamate) in pEffect saranno in sospeso in pClonedEffect

Gli oggetti dispositivo Direct3D 11 seguenti non sono modificabili o mai aggiornati dal framework degli effetti, quindi l'effetto clonato punta agli stessi oggetti dell'effetto originale:

  1. Oggetti a blocchi di stato (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
  2. Shader
  3. Istanze di classe
  4. Trame (non incluse i buffer di trama)
  5. Viste di accesso non ordinate

Gli oggetti dispositivo Direct3D 11 seguenti sono sia modificabili che modificati dal runtime dell'effetto (a meno che non sia gestito dall'utente o singolo in un effetto clonato); le nuove copie di questi oggetti vengono create quando non è singolo:

  1. Buffer costanti
  2. Buffer trama

Buffer costanti singole e buffer di trama

Si noti che questa discussione si applica sia ai buffer costanti che alle trame, ma i buffer costanti vengono assunti per semplificare la lettura.

Potrebbero verificarsi casi in cui un buffer costante viene aggiornato solo da un thread, ma lo stato del dispositivo impostato dagli effetti clonati userà questi dati. Ad esempio, l'effetto principale può aggiornare le matrici di mondo e di visualizzazione a cui si fa riferimento dagli shader negli effetti clonati che non cambiano il mondo e le matrici di visualizzazione. In questi casi, gli effetti clonati devono fare riferimento al buffer costante corrente anziché ricrearne uno.

Esistono due modi per ottenere questo risultato desiderato:

  1. Usare ID3DX11EffectConstantBuffer::SetConstantBuffer sull'effetto clonato per renderlo gestito dall'utente
  2. Contrassegnare il buffer costante come "single" nel codice HLSL, forzando il runtime dell'effetto a trattare è gestito dall'utente dopo la clonazione

Esistono due differenze tra i due metodi precedenti. In primo luogo, nel metodo 1, verrà creato un nuovo ID3D11Buffer e l'utente prima di chiamare SetConstantBuffer. Inoltre, dopo aver chiamato UndoSetConstantBuffer nell'effetto clonato, la variabile nel metodo 1 punta al buffer appena creato (che gli effetti verranno aggiornati su Apply) mentre la variabile nel metodo 2 continuerà a puntare al buffer originale (non aggiornandolo su Apply).

Vedere l'esempio seguente in HLSL:

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

Durante la clonazione, l'effetto clonato creerà un nuovo ID3D11Buffer per ObjectData e riempirà il contenuto in Apply, ma fa riferimento all'ID3D11Buffer originale per ViewData. Il qualificatore singolo può essere ignorato nel processo di clonazione impostando il flag di D3DX11_EFFECT_CLONE_FORCE_NONSINGLE.

Effetti (Direct3D 11)