Klonen eines Effekts
Beim Klonen eines Effekts wird eine zweite, fast identische Kopie des Effekts erstellt. Im folgenden einzelnen Qualifizierer wird erläutert, warum er nicht genau ist. Eine zweite Kopie eines Effekts ist nützlich, wenn Sie das Effektframework für mehrere Threads verwenden möchten, da die Effektlaufzeit nicht threadsicher ist, um eine 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 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:
- Wenn pEffect optimiert ist, ist der pCloned-Effekt optimiert.
- Wenn pEffect über einige vom Benutzer verwaltete Variablen verfügt, verfügt pCloned Effect über dieselben vom Benutzer verwalteten Variablen (siehe die einzelne Beschreibung unten).
- Alle ausstehenden Variablenupdates (bis zum Gerätestatus "Anwenden" aktualisiert) in pEffect sind in pClonedEffect ausstehend.
Die folgenden Direct3D 11-Geräteobjekte sind vom Effektframework unveränderlich oder nie aktualisiert, sodass der geklonte Effekt auf die gleichen Objekte wie der ursprüngliche Effekt verweist:
- Zustandsblockobjekte (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
- Shader
- Klasseninstanzen
- Texturen (ohne Texturpuffer)
- Nicht sortierte 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 keine einzelnen Objekte sind:
- Konstantenpuffer
- Texturpuffer
Einzelne Konstantenpuffer und Texturpuffer
Beachten Sie, dass diese Diskussion sowohl für Konstantenpuffer als auch für Texturen gilt, konstanten Puffern jedoch zur Vereinfachung des Lesens vorausgesetzt wird.
Es kann fälle geben, in denen ein konstanter Puffer nur von einem Thread aktualisiert wird, aber der Gerätestatus, der durch geklonte Effekte festgelegt ist, verwendet diese Daten. Beispielsweise kann der Standard-Effekt die Welt- und Ansichtsmatrizen aktualisieren, auf die von Shadern in geklonten Effekten verwiesen wird, die die Welt- und Ansichtsmatrizen nicht ändern. In diesen Fällen müssen die geklonten Effekte auf den aktuellen Konstantenpuffer verweisen, anstatt einen zu erstellen.
Es gibt zwei Möglichkeiten, dieses gewünschte Ergebnis zu erzielen:
- Verwenden Sie ID3DX11EffectConstantBuffer::SetConstantBuffer für den geklonten Effekt, um ihn benutzerseitig verwaltet zu machen.
- Markieren Sie den Konstantenpuffer als "single" im HLSL-Code, wodurch erzwungen wird, dass die Effektlaufzeit nach dem Klonen 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 Aufrufen von UndoSetConstantBuffer im geklonten Effekt auf den neu erstellten Puffer (der bei Apply aktualisiert wird), während die Variable in Methode 2 weiterhin auf den ursprünglichen Puffer verweist (nicht auf Apply aktualisiert).
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 auf Apply, verweist jedoch auf den ursprünglichen ID3D11Buffer für ViewData. Der einzelne Qualifizierer kann im Klonprozess ignoriert werden, indem das flag D3DX11_EFFECT_CLONE_FORCE_NONSINGLE festgelegt wird.
Zugehörige Themen