Klonen eines Effekts

Beim Klonen eines Effekts wird eine zweite, fast identische Kopie des Effekts erstellt. Im folgenden einzelnen Qualifizierer finden Sie eine Erläuterung, warum er nicht genau ist. Eine zweite Kopie eines Effekts ist nützlich, wenn das Auswirkungsframework für mehrere Threads verwendet werden soll, da die Effektlaufzeit nicht threadsicher ist, um eine hohe Leistung aufrechtzuerhalten.

Da Gerätekontexte auch nicht threadsicher sind, sollten verschiedene Threads verschiedene Gerätekontexte an die ID3DX11EffectPass::Apply-Methode übergeben.

Ein Effekt kann mit der folgenden Syntax geklont werden:

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

Im obigen Beispiel kapselt die geklonte Kopie den gleichen Zustand wie der ursprüngliche Effekt, unabhängig davon, in welchem Zustand sich der ursprüngliche Effekt befindet. Dies gilt insbesondere für:

  1. Wenn pEffect optimiert ist, wird pCloned Effect optimiert.
  2. Wenn pEffect über einige vom Benutzer verwaltete Variablen verfügt, weist pCloned Effect die gleichen vom Benutzer verwalteten Variablen auf (siehe einzelne Beschreibung unten).
  3. Alle ausstehenden Variablenupdates (bis ein Aufruf anwenden den Gerätestatus aktualisiert) in pEffect sind in pClonedEffect ausstehend.

Die folgenden Direct3D 11-Geräteobjekte sind unveränderlich oder werden vom Effektframework nie aktualisiert, sodass der geklonte Effekt auf dieselben Objekte wie der ursprüngliche Effekt verweist:

  1. Zustandsblockobjekte (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
  2. Shader
  3. Klasseninstanzen
  4. Texturen (ohne Texturpuffer)
  5. Ungeordnete Zugriffsansichten

Die folgenden Direct3D 11-Geräteobjekte sind sowohl unveränderlich als auch von der Effektlaufzeit geändert (es sei denn, benutzerseitig verwaltet oder einzeln in einem geklonten Effekt). neue Kopien dieser Objekte werden erstellt, wenn sie nicht einzeln sind:

  1. Konstantenpuffer
  2. Texturpuffer

Einzelne Konstantenpuffer und Texturpuffer

Beachten Sie, dass diese Erläuterung sowohl für konstante Puffer als auch für Texturen gilt, aber konstante Puffer werden zur Vereinfachung des Lesens angenommen.

Es kann Fälle geben, in denen ein konstanter Puffer nur von einem Thread aktualisiert wird, aber der von geklonten Effekten festgelegte Gerätestatus diese Daten verwendet. Beispielsweise kann der Haupteffekt die Welt aktualisieren und Matrizen anzeigen, auf die von Shadern in geklonten Effekten verwiesen wird, die die Welt und die Ansichtsmatrizen nicht ändern. In diesen Fällen müssen die geklonten Effekte auf den aktuellen Konstantenpuffer verweisen, anstatt einen neuen Puffer zu erstellen.

Es gibt zwei Möglichkeiten, dieses gewünschte Ergebnis zu erzielen:

  1. Verwenden Sie ID3DX11EffectConstantBuffer::SetConstantBuffer für den geklonten Effekt, um ihn benutzerverwaltet zu machen.
  2. Markieren Sie den Konstantenpuffer im HLSL-Code als "single", sodass die Auswirkungslaufzeit nach dem Klonen als vom Benutzer verwaltet wird.

Es gibt zwei Unterschiede zwischen den beiden oben genannten Methoden. Zunächst wird in Methode 1 ein neuer ID3D11Buffer erstellt und ein Benutzer erstellt, bevor SetConstantBuffer aufgerufen wird. Außerdem verweist die Variable in Methode 1 nach dem Aufruf von UndoSetConstantBuffer im geklonten Effekt auf den neu erstellten Puffer (die Auswirkungen werden auf Apply aktualisiert), während die Variable in Methode 2 weiterhin auf den ursprünglichen Puffer verweist (ohne sie bei Apply zu aktualisieren).

Sehen Sie sich das folgende Beispiel in HLSL an:

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

Beim Klonen erstellt der geklonte Effekt einen neuen ID3D11Buffer für ObjectData und füllt seinen Inhalt unter Übernehmen aus, verweist jedoch auf den ursprünglichen ID3D11Buffer für ViewData. Der einzelne Qualifizierer kann beim Klonvorgang ignoriert werden, indem das Flag D3DX11 _ EFFECT _ CLONE FORCE _ _ NONSINGLE festgelegt wird.

Effekte (Direct3D 11)