Klonen eines Effekts

Durch das Klonen eines Effekts wird eine zweite, fast identische Kopie des Effekts erstellt. Sehen Sie sich den folgenden einzelnen Qualifizierer an, um zu erklären, warum es nicht genau ist. Eine zweite Kopie eines Effekts ist nützlich, wenn man das Effektframework auf mehreren Threads verwenden möchte, da die Effektlaufzeit nicht threadsicher ist, um hohe Leistung zu gewährleisten.

Da Gerätekontexte auch nicht threadsicher sind, sollten verschiedene Threads unterschiedliche 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 denselben 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, ist 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 die folgende beschreibung)
  3. Alle ausstehenden Variablenupdates (bis ein Gerätestatus des Anwendens von Anrufupdates) in pEffect aussteht in pClonedEffect

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

  1. State block objects (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
  2. Shader
  3. Klasseninstanzen
  4. Texturen (nicht einschließlich Texturpuffer)
  5. Nicht angeordnete Zugriffsansichten

Die folgenden Direct3D 11-Geräteobjekte sind sowohl unveränderlich als auch durch die Effektlaufzeit geändert (es sei denn, benutzerverwaltet 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 Diskussion sowohl für Konstantenpuffer als auch für Texturen gilt, aber Konstantenpuffer werden für eine einfache Lesbarkeit angenommen.

Es kann vorkommen, dass ein Konstantenpuffer nur von einem Thread aktualisiert wird, aber der durch geklonte Effekte festgelegte Gerätezustand verwendet diese Daten. Der Haupteffekt kann beispielsweise die Welt- und Ansichtsmatrizen aktualisieren, auf die von Shadern in geklonten Effekten verwiesen wird, die die Welt nicht ändern und Matrizen anzeigen. In diesen Fällen müssen die geklonten Effekte auf den aktuellen Konstantenpuffer verweisen, anstatt einen neu zu erstellen.

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

  1. Verwenden sie ID3DX11EffectConstantBuffer::SetConstantBuffer für den geklonten Effekt, um es benutzerverwaltet zu machen
  2. Markieren Sie den Konstantenpuffer im HLSL-Code als "single", und erzwingt die Effektlaufzeit nach dem Klonen als vom Benutzer verwaltete Laufzeit.

Es gibt zwei Unterschiede zwischen den beiden oben genannten Methoden. Zunächst wird in Methode 1 ein neuer ID3D11Buffer erstellt und Benutzer verwendet, bevor SetConstantBuffer aufgerufen wird. Außerdem zeigen die Variable in Der Methode 1 nach dem Aufrufen von "UndoSetConstantBuffer" auf den neu erstellten Puffer (welche Effekte auf "Apply" aktualisiert werden), während die Variable in Methode 2 weiterhin auf den ursprünglichen Puffer verweist (nicht aktualisiert auf Apply).

Siehe das folgende Beispiel in HLSL:

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

Während der Klonung erstellt der geklonte Effekt einen neuen ID3D11Buffer für ObjectData, und füllen Sie den Inhalt auf Apply, verweisen Sie jedoch auf das ursprüngliche ID3D11Buffer für ViewData. Der einzelne Qualifizierer kann im Klonprozess ignoriert werden, indem das D3DX11_EFFECT_CLONE_FORCE_NONSINGLE Flag festgelegt wird.

Effekte (Direct3D 11)