Sdílet prostřednictvím


Klonování efektu

Klonování efektu vytvoří druhou, téměř identickou kopii efektu. Vysvětlení, proč není přesné, najdete v následujícím jediném určení. Druhá kopie efektu je užitečná, když chcete použít architekturu efektů na více vláknech, protože modul runtime efektu není bezpečný pro zajištění vysokého výkonu.

Vzhledem k tomu, že kontexty zařízení nejsou bezpečné pro přístup z více vláken, měly by různé vlákna předávat různé kontexty zařízení do metody ID3DX11EffectPass::Apply.

Efekt lze naklonovat s následující syntaxí:

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

V předchozím příkladu klonovaná kopie zachová stejný stav jako původní efekt, nezávisle na tom, v jakém stavu se původní efekt nachází. Zejména:

  1. Pokud je pEffect optimalizovaný, je pCloned Effect také optimalizovaný.
  2. Pokud má pEffect některé proměnné spravované uživatelem, bude mít efekt pCloned stejné proměnné spravované uživatelem (viz jeden popis níže).
  3. Veškeré čekající aktualizace proměnných (dokud nedojde ke zpracování volání funkce Apply, které aktualizuje stav zařízení) budou čekat i ve funkci pClonedEffect.

Následující objekty zařízení Direct3D 11 jsou neměnné nebo nikdy aktualizovány architekturou efektů, takže klonovaný efekt bude odkazovat na stejné objekty jako původní efekt:

  1. Stavové blokové objekty (ID3D11BlendState, ID3D11RasterizerState, ID3D11DepthStencilState, ID3D11SamplerState)
  2. Shadery
  3. Instance třídy
  4. Textury (s výjimkou vyrovnávacích pamětí textur)
  5. Neuspořádané zobrazení přístupu

Následující objekty zařízení Direct3D 11 jsou buď neměnné, nebo upravené modulem runtime efektu (pokud nejsou spravovány uživatelem nebo nejsou unikátní v klonovaném efektu); nové kopie těchto objektů se vytvoří, pokud nejsou unikátní:

  1. Konstantní vyrovnávací paměti
  2. Texturové buffery

Vyrovnávací paměti s jednou konstantou a vyrovnávací paměti textury

Upozorňujeme, že tato diskuze se týká konstantních vyrovnávacích pamětí i textur, ale pro snadné čtení se předpokládá konstantní vyrovnávací paměť.

Mohou existovat případy, kdy konstantní vyrovnávací paměť je aktualizována pouze jedním vláknem, ale stav zařízení nastavený klonovanými efekty bude tato data používat. Hlavní efekt může například aktualizovat modelové a pohledové matice, na které se odkazuje z shaderů v klonovaných efektech, jež nemění tyto matice. V těchto případech by klonované efekty měly odkazovat na aktuální konstantní vyrovnávací paměť místo jejího znovuvytváření.

Tento požadovaný výsledek můžete dosáhnout dvěma způsoby:

  1. Použijte ID3DX11EffectConstantBuffer::SetConstantBuffer na klonovaném efektu, aby ho mohl spravovat uživatel.
  2. Označte konstantní vyrovnávací paměť jako "single" v kódu HLSL, čímž vynutíte, aby modul runtime efektu po klonování považoval paměť za spravovanou uživatelem.

Mezi výše dvěma metodami existují dva rozdíly. Nejprve se v metodě 1 vytvoří nový ID3D11Buffer a použije se před zavoláním SetConstantBuffer. Také po volání UndoSetConstantBuffer v klonovaném efektu proměnná v metodě 1 přejde na nově vytvořenou vyrovnávací paměť (kterou účinky aktualizují při použití), zatímco proměnná v metodě 2 bude nadále odkazovat na původní vyrovnávací paměť (která se při použití neaktualizuje).

Podívejte se na následující příklad v HLSL:

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

Při klonování klonovaný efekt vytvoří nový ID3D11Buffer pro ObjectData a při aplikaci vyplní jeho obsah, ale odkazuje na původní ID3D11Buffer pro ViewData. Jeden parametr může být při klonování ignorován nastavením příznaku D3DX11_EFFECT_CLONE_FORCE_NONSINGLE.

Efekty (Direct3D 11)