Sdílet prostřednictvím


Propojení efektových shaderů

Direct2D používá optimalizaci nazvanou propojení efektových shaderů, která kombinuje více průchodů vykreslování grafu s efekty do jednoho jednotného průchodu.

Přehled propojení shaderu efektů

Optimalizace propojení efektových shaderů je postavena na propojení HLSL shaderů, funkce Direct3D 11.2, která umožňuje generování pixelových a vertexových shaderů během běhu propojením předkompilovaných funkcí shaderu. Následující obrázky znázorňují koncept propojení efektových shaderů v grafu efektů. První obrázek znázorňuje typický graf efektu Direct2D se čtyřmi transformacemi vykreslování. Bez propojení shaderu každá transformace využívá vykreslovací průchod a vyžaduje mezipovrch; tento graf celkem vyžaduje 4 průchody a 3 mezipovrchy.

transformace grafu bez spojování shaderu: 4 průchody a 3 meziprodukty.

Druhý obrázek ukazuje stejný graf efektu, ve kterém byla každá transformace vykreslování nahrazena verzí odkazovatelné funkce. Direct2D dokáže propojit celý graf a spustit ho v jednom průchodu bez nutnosti zprostředkujících prvků. To může přinést výrazné snížení doby provádění GPU a snížení spotřeby paměti GPU ve špičce.

transformovat graf s propojením shaderu: 1 průchod, 0 mezičlánků.

 

Propojení shaderu pro efekt funguje na jednotlivých transformacích v efektu, což znamená, že i graf s jedním efektem může mít prospěch z propojení shaderu, pokud tento efekt obsahuje více validních transformací.

Použití propojení efektového shaderu

Pokud vytváříte aplikaci Direct2D, která používá efekty, nemusíte nic dělat, abyste využili výhod propojení shaderu efektů. Direct2D automaticky analyzuje graf efektů, aby určil optimální způsob propojení jednotlivých transformací.

Autoři efektů zodpovídají za implementaci jejich efektu způsobem, který podporuje propojení shaderu efektů; Další informace najdete v části Vytvoření vlastního efektu kompatibilního s propojením shaderu níže. Všechny integrované efekty podporují propojení shaderu.

Direct2D propojí pouze sousední transformace vykreslování v situacích, pokud je to výhodné. Při určování, zda se mají propojit dvě transformace, bere v úvahu několik faktorů. Propojení shaderu se například neprovádí, pokud některá z transformací používá vrcholový nebo výpočetní shader, protože lze propojit pouze pixelové shadery. Pokud nebyl efekt vytvořený tak, aby byl kompatibilní s propojením shaderu, nebudou s ním spojené okolní transformace.

V případě, že takové nebezpečí propojení existuje, Direct2D nepropojí žádné transformace sousedící s rizikem, ale stále se pokusí propojit zbytek grafu.

transformovat graf s rizikem propojení: 2 průchody, 1 mezikrok.

Vytvoření vlastního efektu kompatibilního s propojením shaderu

Pokud vytváříte vlastní efekt Direct2D, musíte zajistit, aby jeho transformace podporovaly propojení shaderu efektů. To vyžaduje několik menších změn z toho, jak byly implementovány předchozí vlastní efekty. Pokud transformace ve vašem vlastním efektu nepodporuje propojení shaderu, Direct2D ho nebude propojit s žádnými transformacemi, které jsou vedle ní v grafu efektu.

Jako autor vlastního efektu byste měli znát několik klíčových konceptů a požadavků:

  • Žádné změny, které by ovlivnily implementace rozhraní

    Není nutné upravovat žádný kód pro implementaci různých rozhraní efektů, jako je ID2D1DrawTransform.

  • Poskytnout úplnou i exportní verzi funkcí shaderů

    Je nutné zadat verzi funkce exportu shaderů efektu, které lze propojit pomocí Direct2D. Kromě toho musíte i nadále poskytovat původní, plný shader; Důvodem je to, že Direct2D vybere za běhu správnou verzi shaderu v závislosti na tom, jestli se má propojení shaderu použít na konkrétní odkaz v grafu.

    Pokud transformace poskytuje pouze úplný objekt blob pixelového shaderu (prostřednictvím ID2D1EffectContext::LoadPixelShader), nebude propojen se sousedními transformacemi.

  • Pomocné funkce

    Direct2D poskytuje pomocné funkce HLSL a makra, která automaticky vygenerují úplné i exportní verze shaderu. Tyto pomocné programové rutiny najdete v souboru d2d1effecthelpers.hlsli. Kromě toho kompilátor HLSL (FXC) umožňuje vložit shader funkce exportu do privátního pole v plném shaderu. Tímto způsobem stačí vytvořit shader jen jednou a současně předat obě verze Direct2D. d2d1effecthelpers.hlsli i kompilátor FXC jsou součástí sady Windows SDK.

    Pomocné funkce:

    Můžete také ručně vytvořit dvě verze každého shaderu a zkompilovat je dvakrát, pokud jsou splněny specifikace popsané níže v specifikace funkce exportu.

  • pouze pixelové shadery

    Direct2D nepodporuje propojení výpočetních nebo vrcholových shaderů. Pokud ale váš efekt používá vrcholový a pixelový shader, může být výstup pixelového shaderu stále propojen.

  • jednoduché vs složité vzorkování

    Propojení funkcí shaderů funguje tak, že výstup jednoho pixelového shaderu je připojen ke vstupu následného pixelového shaderu. To je možné pouze v případě, že pixelový shader vyžaduje pouze jednu vstupní hodnotu k provedení svého výpočtu; tato hodnota by obvykle pocházela ze vzorkování vstupní textury v souřadnicích textury vygenerovaných vrcholovým shaderem. Takový pixel shader se označuje jako provádějící jednoduché vzorkování.

    převod stupně šedé je příkladem jednoduchého vzorkování. Hodnota konkrétního výstupního pixelu závisí pouze na hodnotě odpovídajícího vstupního pixelu.

    Některé pixelové shadery, jako je Gaussovo rozostření, vypočítávají svůj výstup z více vstupních vzorků, nikoli z jediného vzorku. Říká se, že takový pixelový shader provádí komplexní vzorkování.

    gaussovské rozostření je příkladem komplexního vzorkování. hodnota středového výstupního pixelu závisí na více vstupních pixelech.

    Pouze funkce shaderu s jednoduchými vstupy mohou mít svůj vstup poskytovaný jinou funkcí shaderu. Funkce shaderu se složitými vstupy musí být poskytovány se vstupní texturou pro vzorkování. To znamená, že Direct2D nebude propojit shader se složitými vstupy s jeho předchůdcem.

    Při použití pomocných rutin Direct2D HLSLje nutné indikovat v HLSL, zda shader používá složité nebo jednoduché vstupy.

Příklad shaderu efektu kompatibilního s propojením

Použitím D2D pomocných rutin představuje následující fragment kódu jednoduchý efektový shader kompatibilní s propojením:

#define D2D_INPUT_COUNT 1
#define D2D_INPUT0_SIMPLE
#include “d2d1effecthelpers.hlsli”

D2D_PS_ENTRY(LinkingCompatiblePixelShader)
{
    float4 input = D2DGetInput(0);
    input.rgb *= input.a;
    return input;
}          

V tomto krátkém příkladu si všimněte, že nejsou deklarovány žádné parametry funkce, že počet vstupů a typ každého vstupu je deklarován před vstupní funkcí, vstup se načte voláním D2DGetInputa že direktivy preprocesoru musí být definovány před zahrnutím pomocného souboru.

Shader, který je kompatibilní s propojením, musí poskytovat jak normální jednopramenný pixelový shader, tak i exportní funkci shaderu. Makro D2D_PS_ENTRY umožňuje, aby se každý z nich vygeneroval ze stejného kódu, pokud se používá ve spojení se skriptem kompilace shaderu.

Při kompilaci úplného shaderu se makra rozbalí do následujícího kódu, který má vstupní podpis kompatibilní s efekty D2D.

Texture2D<float4> InputTexture0;
SamplerState InputSampler0;

float4 LinkingCompatiblePixelShader(
    float4 pos   : SV_POSITION,
    float4 posScene : SCENE_POSITION,
    float4 uv0  : TEXCOORD0
    ) : SV_Target
    {
        float4 input = InputTexture0.Sample(InputSampler0, uv0.xy);
        input.rgb *= input.a;
        return input;
    }    

Při kompilaci verze funkce exportu stejného kódu se vygeneruje následující kód:

// Shader function version
export float4 LinkingCompatiblePixelShader_Function(
    float4 input0 : INPUT0)
    {
        input.rgb *= input.a;
        return input;
    }      

Všimněte si, že vstup textury, který se obvykle načítá vzorkováním Textury2D, byl nahrazen vstupem funkce (input0).

Pokud chcete zobrazit úplný podrobný popis toho, co potřebujete udělat k napsání efektu kompatibilního s propojováním, podívejte se na návod na vlastní efekty a vzorový příklad vlastních efektů Direct2D.

Kompilace kompatibilního shaderu pro linkování

Aby bylo možné propojit blob pixelového shaderu předaný do D2D, musí obsahovat jak úplnou, tak i exportní verzi funkce shaderu. Toho dosáhnete vložením zkompilované funkce exportu do D3D_BLOB_PRIVATE_DATA oblasti.

Při vytváření shaderů pomocí pomocných funkcí D2D musí být v době kompilace definován cíl kompilace D2D. Cílové typy kompilace jsou D2D_FULL_SHADER a D2D_FUNCTION.

Kompilace efektového shaderu kompatibilního s propojováním je dvoustupňový proces.

Poznámka

Při kompilaci efektu pomocí sady Visual Studio byste měli vytvořit dávkový soubor, který spouští příkazy FXC a spustí tento dávkový soubor jako vlastní krok sestavení, který se spustí před krokem kompilace.

 

Krok 1: Kompilace funkce exportu

fxc /T <shadermodel> <MyShaderFile>.hlsl /D D2D_FUNCTION /D D2D_ENTRY=<entry> /Fl <MyShaderFile>.fxlib           

Pokud chcete zkompilovat verzi funkce exportu shaderu, musíte do FXC předat následující příznaky.

Vlajka Popis
/T <ShaderModel> Nastavte <ShaderModel> na příslušný profil shaderu pixelů definovaný v syntaxi FXC. Musí se jednat o jeden z profilů uvedených v části „Propojení shaderu HLSL“.
<MyShaderFile>.hlsl Nastavte <MyShaderFile> na název souboru HLSL.
/D D2D_FUNCTION Tato definice dává FXC pokyn, aby zkompiloval verzi funkce exportu shaderu.
/D D2D_ENTRY=<položka> Nastavte <položku> na název vstupního bodu HLSL, který jste definovali uvnitř makra D2D_PS_ENTRY.
/Fl <MyShaderFile>.fxlib Nastavte <MyShaderfile> na místo, kam chcete uložit verzi funkce exportu shaderu. Všimněte si, že rozšíření .fxlib je pouze pro snadnou identifikaci.

Krok 2: Kompilace úplného shaderu a vložení funkce exportu

fxc /T ps_<shadermodel> <MyShaderFile>.hlsl /D D2D_FULL_SHADER /D D2D_ENTRY=<entry> /E <entry> /setprivate <MyShaderFile>.fxlib /Fo <MyShader>.cso /Fh <MyShader>.h           

Pokud chcete zkompilovat plnou verzi shaderu s vloženou verzí exportu, musíte do FXC předat následující příznaky.

Vlajka Popis
/T <ShaderModel> Nastavte <ShaderModel> na příslušný profil shaderu pixelů definovaný v syntaxi FXC. Musí se jednat o profil shaderu pixelů odpovídající profilu propojení zadanému v kroku 1.
<MyShaderFile>.hlsl Nastavte <MyShaderFile> na název souboru HLSL.
/D D2D_FULL_SHADER Tato definice dává FXC pokyn ke kompilaci úplné verze shaderu.
/D D2D_ENTRY=<položka> Nastavte <položku> na název vstupního bodu HLSL, který jste definovali uvnitř makra D2D_PS_ENTRY().
Položka /E <> Nastavte <položku> na název vstupního bodu HLSL, který jste definovali uvnitř makra D2D_PS_ENTRY().
/setprivate <MyShaderFile>.fxlib Tento argument dává FXC pokyn, aby vložil shader funkce exportu vygenerovaný v kroku 1 do D3D_BLOB_PRIVATE_DATA oblasti.
/Fo <MyShader>.cso Nastavte <MyShader> na místo, kam chcete uložit konečný kompilovaný shader.
/Fh <MyShader>.h Nastavte <MyShader> na místo, kam chcete uložit konečné kombinované záhlaví.

Specifikace funkce exportu

Je možné – i když se to nedoporučuje – vytvořit kompatibilní shader efektu bez použití nástrojů poskytovaných D2D. Je třeba dbát na to, aby vstupní podpisy funkcí full shader i exportu odpovídaly specifikacím D2D.

Specifikace pro úplné shadery jsou stejné jako starší verze Windows. Stručně řečeno, vstupní parametry pixelového shaderu musí být SV_POSITION, SCENE_POSITION a jeden TEXCOORD pro každý vstup efektu.

Pro funkci exportu musí funkce vrátit hodnotu float4 a její vstupy musí být jedním z následujících typů:

  • Jednoduchý vstup

    float4 d2d_inputN : INPUTN         
    

    Pro jednoduché vstupy D2D buď vloží funkci vzorkování mezi vstupní texturu a funkci shaderu, nebo bude vstup poskytnut výstupem jiné funkce shaderu.

  • Složitý vstup

    float4 d2d_uvN  : TEXCOORDN                
    

    U složitých vstupů D2D předá souřadnici textury, jak je popsáno v dokumentaci k Systému Windows 8.

  • Umístění výstupu

    float4 d2d_posScene : SCENE_POSITION                
    

    Lze definovat pouze jeden SCENE_POSITION vstup. Tento parametr by měl být zahrnut pouze v případě potřeby, protože tento parametr může využívat pouze jedna funkce na propojený shader.

Sémantika musí být definována jako výše, protože D2D zkontroluje sémantiku a rozhodne se, jak propojit funkce. Pokud některý vstup funkce neodpovídá některému z výše uvedených typů, funkce bude odmítnuta pro propojení shaderu.

pomocníci HLSL

rozhraní ID3D11Linker

rozhraní ID3D11FunctionLinkingGraph