効果の複製

効果を複製すると、効果の 2 つ目のコピーとほぼ同じコピーが作成されます。 正確でない理由については、次の単一修飾子を参照してください。 効果の 2 番目のコピーは、効果ランタイムが高いパフォーマンスを維持するためにスレッド セーフではないため、複数のスレッドで効果フレームワークを使用する場合に便利です。

デバイス コンテキストはスレッド セーフでないため、異なるスレッドは異なるデバイス コンテキストを ID3DX11EffectPass::Apply メソッドに渡す必要があります。

効果は、次の構文で複製できます。

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

上の例では、複製されたコピーは、元の効果の状態に関係なく、元の効果と同じ状態をカプセル化します。 特に次の点に違いがあります。

  1. pEffect が最適化されている場合、pCloned Effect は最適化されます
  2. pEffect にユーザー管理変数がある場合、pCloned Effect には同じユーザーマネージド変数が含まれます (以下の単一の説明を参照してください)
  3. pEffect の保留中の変数の更新 (Apply 呼び出しがデバイスの状態を更新するまで) は、pClonedEffect で保留中になります

次の Direct3D 11 デバイス オブジェクトは変更できないか、効果フレームワークによって更新されないため、複製された効果は元の効果と同じオブジェクトを指します。

  1. State ブロック オブジェクト (ID3D11BlendState、ID3D11RasterizerState、ID3D11DepthStencilState、ID3D11SamplerState)
  2. シェーダー
  3. クラス インスタンス
  4. テクスチャ (テクスチャ バッファーを含まない)
  5. 順序指定されていないアクセス ビュー

次の Direct3D 11 デバイス オブジェクトは、どちらも変更不可であり、効果ランタイムによって変更されます (ユーザーが管理している場合、または複製された効果で単一である場合を除く)。これらのオブジェクトの新しいコピーは、単一でない場合に作成されます。

  1. 定数バッファー
  2. テクスチャ バッファー

単一定数バッファーとテクスチャ バッファー

この説明は定数バッファーとテクスチャの両方に適用されますが、読みやすくするために定数バッファーが想定されていることに注意してください。

定数バッファーが 1 つのスレッドによってのみ更新される場合がありますが、複製された効果によって設定されたデバイスの状態では、このデータが使用されます。 たとえば、メイン効果は、ワールドとビューマトリックスを変更しない複製効果のシェーダーから参照されるワールドとビューマトリックスを更新できます。 このような場合、複製された効果は、再作成するのではなく、現在の定数バッファーを参照する必要があります。

この目的の結果を得るには、次の 2 つの方法があります。

  1. 複製された効果で ID3DX11EffectConstantBuffer::SetConstantBuffer を使用して、ユーザーが管理できるようにします
  2. HLSL コードで定数バッファーを "単一" としてマークし、複製後にエフェクト ランタイムがユーザー管理として扱うように強制する

上記の 2 つの方法には 2 つの違いがあります。 まず、メソッド 1 では、新しい ID3D11Buffer が作成され、SetConstantBuffer が呼び出される前にユーザーが作成されます。 また、複製された効果で UndoSetConstantBuffer を呼び出した後、メソッド 1 の変数は新しく作成されたバッファー (Apply で効果が更新されます) を指しますが、メソッド 2 の変数は元のバッファーを指し続けます (Apply では更新されません)。

HLSL の次の例を参照してください。

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

複製中に、複製された効果は ObjectData 用に新しい ID3D11Buffer を作成し、その内容を [適用] に入力しますが、ViewData の元の ID3D11Buffer を参照します。 D3DX11_EFFECT_CLONE_FORCE_NONSINGLE フラグを設定することで、複製プロセスで単一修飾子を無視できます。

効果 (Direct3D 11)