Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Funkcja Direct2D używa optymalizacji nazywanej łączeniem shaderów efektów, która łączy kilkukrotne przejścia renderowania efektów graficznych w jedno.
- Przegląd łączenia shaderów efektów
- linkowanie shaderów efektów
- Tworzenie niestandardowego efektu zgodnego z łączeniem shaderów
- Przykładowy shader efektu zgodny z łączeniem
- Kompilowanie kompatybilnego shadera dla łączenia
- Eksportuj specyfikacje funkcji
- Tematy pokrewne
Omówienie łączenia shaderów efektu
Optymalizacje łączenia shaderów efektu są oparte na łączeniu shaderów HLSL, cesze Direct3D 11.2, która umożliwia generowanie shaderów pikseli i wierzchołków w czasie wykonywania przez powiązanie wstępnie skompilowanych funkcji shaderów. Na poniższych ilustracjach przedstawiono koncepcję łączenia shaderów efektów w wykresie efektowym. Pierwsza ilustracja przedstawia typowy wykres efektu Direct2D z czterema transformacjami renderowania. Bez łączenia shaderów każda transformacja wymaga przejścia renderowania i powierzchni pośredniej; w sumie ten graf wymaga 4 przebiegów i 3 pośrednich.
Druga ilustracja przedstawia ten sam wykres efektu, w którym każda transformacja renderowania została zastąpiona wersją funkcji z możliwością łączenia. Direct2D jest w stanie połączyć cały graf i wykonać go w jednym przebiegu bez wymagania żadnych pośrednich. Może to zapewnić znaczny spadek czasu wykonywania procesora GPU i zmniejszenie maksymalnego użycia pamięci procesora GPU.
Łączenie cieniowania efektów działa na poszczególnych przekształceniach w ramach efektu; Oznacza to, że nawet wykres z pojedynczym efektem może korzystać z łączenia cieniowania, jeśli ten efekt ma wiele prawidłowych przekształceń.
Używanie łączenia shaderów efektu
Jeśli tworzysz aplikację Direct2D, która używa efektów, nie musisz podejmować żadnych działań, aby skorzystać z łączenia cieniowania efektów. Funkcja Direct2D automatycznie analizuje wykres efektów, aby określić najbardziej optymalny sposób łączenia każdej transformacji.
Autorzy efektów są odpowiedzialni za zaimplementowanie swoich efektów w sposób, który wspiera łączenie shaderów efektów; aby uzyskać więcej informacji, zobacz sekcję Tworzenie efektu zgodnego z połączeniem shaderów poniżej. Wszystkie wbudowane efekty obsługują łączenie shaderów.
Funkcja Direct2D łączy sąsiadujące przekształcenia renderowania tylko w sytuacjach, gdy jest to korzystne. Uwzględnia wiele czynników podczas określania, czy połączyć dwa przekształcenia. Na przykład łączenie shaderów nie jest wykonywane, jeśli jedna z transformacji używa shaderów wierzchołków lub shaderów obliczeniowych, ponieważ można połączyć tylko shadery pikseli. Ponadto, jeśli efekt nie został utworzony jako zgodny z łączeniem cieniowania, otaczające przekształcenia nie będą z nim powiązane.
W przypadku, gdy takie zagrożenie łączenia istnieje, Direct2D nie będzie łączyć żadnych przekształceń sąsiadujących z zagrożeniem, ale nadal podejmie próbę połączenia pozostałej części grafu.
Tworzenie niestandardowego efektu kompatybilnego z łączeniem shaderów
Jeśli tworzysz własny niestandardowy efekt Direct2D, musisz upewnić się, że jego transformacje obsługują łączenie shadera efektu. Wymaga to pewnych drobnych zmian w sposobie implementacji poprzednich efektów niestandardowych. Jeśli transformacja w ramach efektu niestandardowego nie obsługuje łączenia shaderów, funkcja Direct2D nie połączy jej z żadnymi przekształceniami przylegającymi do niej w grafie efektowym.
Jako autor efektów niestandardowych należy pamiętać o kilku kluczowych pojęciach i wymaganiach:
Brak zmian w implementacjach interfejsu
Nie trzeba modyfikować żadnego kodu implementowania różnych interfejsów efektu, takich jak ID2D1DrawTransform.
Podaj pełną i eksportową wersję funkcji cieniowania
Należy podać wersję funkcji eksportu cieniowania efektu, które można połączyć za pomocą funkcji Direct2D. Ponadto należy nadal udostępniać oryginalny, pełny cieniator; Dzieje się tak, ponieważ funkcja Direct2D wybiera w czasie wykonywania odpowiednią wersję cieniowania w zależności od tego, czy łączenie cieniowania ma być stosowane do określonego linku na wykresie.
Jeśli przekształcenie zapewnia tylko pełny shader piksela (za pośrednictwem ID2D1EffectContext::LoadPixelShader), nie będzie połączone z sąsiednimi przekształceniami.
Funkcje pomocnicze
Direct2D zapewnia funkcje pomocnicze HLSL i makra, które automatycznie generują zarówno pełną, jak i eksportującą wersję funkcji cieniowania. Te pomocniki można znaleźć w d2d1effecthelpers.hlsli. Ponadto, kompilator HLSL (FXC) umożliwia wstawienie shadera funkcji eksportu do pola prywatnego w pełnym shaderze. W ten sposób wystarczy utworzyć cieniowanie tylko raz i przekazać obie wersje do direct2D jednocześnie. Zarówno d2d1effecthelpers.hlsli, jak i kompilator FXC są zawarte w ramach zestawu Windows SDK.
Funkcje pomocnika:
- D2DGetInput
- D2DSampleInput
- D2DSampleInputAtOffset
- D2DSampleInputAtPosition
- D2DGetInputCoordinate
- D2DGetScenePosition
- D2D_PS_ENTRY
Można również ręcznie utworzyć dwie wersje każdego cieniowania i skompilować je dwa razy, o ile specyfikacje opisane poniżej w Eksportuj specyfikacje funkcji są spełnione.
Cieniowanie pikseli tylko
Direct2D nie obsługuje łączenia shaderów obliczeniowych ani wierzchołkowych. Jeśli jednak efekt używa zarówno shaderów wierzchołków, jak i pikseli, wynik działania shadera pikseli wciąż można połączyć.
proste i złożone próbkowanie
Łączenie funkcji cieniowania działa przez połączenie danych wyjściowych cieniowania jednego piksela z wejściem kolejnego przebiegu cieniowania pikseli. Jest to możliwe tylko wtedy, gdy cieniowanie pikseli zużywające wymaga tylko jednej wartości wejściowej do wykonania obliczeń; ta wartość zwykle pochodziłaby z próbkowania tekstury wejściowej na współrzędnych tekstury emitowanych przez cieniowanie wierzchołków. Taki shader pikseli jest znany z wykonywania prostego próbkowania.
Niektóre shadery pikseli, takie jak rozmycie Gaussa, obliczają dane wyjściowe z wielu próbek wejściowych, a nie tylko pojedynczej próbki. Taki shader pikseli wykonuje złożone próbkowanie.
Tylko funkcje cieniowania z prostymi danymi wejściowymi mogą mieć dane wejściowe udostępniane przez inną funkcję cieniowania. Funkcje cieniowania ze złożonymi danymi wejściowymi muszą być dostarczane z teksturą wejściową do próbkowania. Oznacza to, że Direct2D nie połączy shaderu ze złożonymi danymi wejściowymi ze swoim poprzednikiem.
W przypadku korzystania z pomocników HLSL Direct2Dnależy wskazać w HLSL, czy cieniator używa złożonych lub prostych danych wejściowych.
Przykładowy shader efektu zgodnego z połączeniem
Korzystając z pomocników D2D, poniższy fragment kodu reprezentuje prosty shader efektu kompatybilny z linkowaniem.
#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;
}
W tym krótkim przykładzie zwróć uwagę, że nie zadeklarowano żadnych parametrów funkcji, że liczba danych wejściowych i typ poszczególnych danych wejściowych jest zadeklarowana przed funkcją entry, dane wejściowe są pobierane przez wywołanie D2DGetInputi że dyrektywy preprocesora muszą być zdefiniowane przed dołączenia pliku pomocniczego.
Shader zgodny z łączeniem musi zapewnić zarówno jednoprzepustowy shader pikseli, jak i funkcję eksportu shadera. Makro D2D_PS_ENTRY umożliwia wygenerowanie każdego z nich na podstawie tego samego kodu, gdy jest używane w połączeniu ze skryptem kompilacji cieniowania.
Podczas kompilowania pełnego cieniowania makra są rozszerzane na następujący kod, który ma sygnaturę wejściową zgodną z efektami 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;
}
Podczas kompilowania wersji funkcji eksportu tego samego kodu jest generowany następujący kod:
// Shader function version
export float4 LinkingCompatiblePixelShader_Function(
float4 input0 : INPUT0)
{
input.rgb *= input.a;
return input;
}
Należy pamiętać, że dane wejściowe tekstury, zwykle pobierane przez próbkowanie tekstury2D, zostały zastąpione danymi wejściowymi funkcji (input0).
Aby zapoznać się z pełnym, krok po kroku opisem tworzenia efektu kompatybilnego z łączeniem, zapoznaj się z samouczkiem Efekty niestandardowe oraz przykładem Efekty niestandardowe obrazu Direct2D.
Kompilowanie łączenia zgodnego cieniowania
Aby można było zlinkować, blob shadera pikseli przekazany do D2D musi zawierać zarówno pełne wersje funkcji, jak i eksportowane wersje shadera. Jest to realizowane przez osadzenie skompilowanej funkcji eksportu w obszarze D3D_BLOB_PRIVATE_DATA.
Gdy shadery są tworzone za pomocą funkcji pomocniczych D2D, cel kompilacji D2D musi być zdefiniowany w czasie kompilacji. Typy docelowe kompilacji są D2D_FULL_SHADER i D2D_FUNCTION.
Kompilowanie kompatybilnego z linkowaniem shaderu efektu to proces dwuetapowy:
Notatka
Podczas kompilowania efektu przy użyciu programu Visual Studio należy utworzyć plik wsadowy, który wykonuje polecenia FXC i uruchamia ten plik wsadowy jako niestandardowy krok kompilacji uruchamiany przed krokiem kompilacji.
Krok 1. Kompilowanie funkcji eksportu
fxc /T <shadermodel> <MyShaderFile>.hlsl /D D2D_FUNCTION /D D2D_ENTRY=<entry> /Fl <MyShaderFile>.fxlib
Aby skompilować wersję funkcji eksportu dla twojego shadera, należy przekazać następujące flagi do FXC.
| Flaga | Opis |
|---|---|
| /T <ShaderModel> | Ustaw <ShaderModel> na odpowiedni profil cieniowania pikseli zgodnie z definicją w FXC Syntax. To musi być jeden z profilów wymienionych w sekcji "Łączenie shaderów HLSL". |
| <MyShaderFile>.hlsl | Ustaw <MyShaderFile> na nazwę pliku HLSL. |
| /D D2D_FUNCTION | Ta definicja instruuje FXC, aby skompilował wersję funkcji eksportu shader. |
| /D D2D_ENTRY=<wpis> | Ustaw wartość <na nazwę> punktu wejściowego HLSL zdefiniowanego wewnątrz makra D2D_PS_ENTRY. |
| /Fl <MyShaderFile>.fxlib | Ustaw <MyShaderfile> w miejscu, gdzie chcesz przechowywać wersję funkcji eksportującej shader. Należy pamiętać, że rozszerzenie fxlib jest tylko w celu ułatwienia identyfikacji. |
Krok 2. Kompilowanie pełnego cieniowania i osadzanie funkcji eksportu
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
Aby skompilować pełną wersję shader z osadzoną wersją eksportu, należy przekazać następujące flagi do FXC.
| Flaga | Opis |
|---|---|
| /T <ShaderModel> | Ustaw <ShaderModel> na odpowiedni profil cieniowania pikseli zgodnie z definicją w FXC Syntax. Musi to być profil cieniowania pikseli odpowiadający profilowi łączenia określonemu w kroku 1. |
| <MyShaderFile>.hlsl | Ustaw <MyShaderFile> na nazwę pliku HLSL. |
| /D D2D_FULL_SHADER | Ta definicja nakazuje FXC skompilowanie pełnej wersji cieniowania. |
| /D D2D_ENTRY=<wpis> | Ustaw <pozycję> na nazwę punktu startowego HLSL określonego wewnątrz makra D2D_PS_ENTRY(). |
| /E <wejście> | Ustaw <elementu> na nazwę punktu wejścia HLSL, który zdefiniowałeś wewnątrz makra D2D_PS_ENTRY(). |
| /setprivate <MyShaderFile>.fxlib | Ten argument instruuje FXC, aby osadzić moduł cieniowania funkcji eksportu wygenerowany w kroku 1 w obszarze D3D_BLOB_PRIVATE_DATA. |
| /Fo <MyShader>.cso | Ustaw <MyShader> w miejscu, w którym chcesz przechowywać ostateczny, połączony skompilowany shader. |
| /Fh <MyShader>.h | Ustaw <MyShader> w miejsce, gdzie chcesz przechowywać ostatni, połączony nagłówek. |
Eksportowanie specyfikacji funkcji
Istnieje możliwość – choć nie jest to zalecane – aby utworzyć zgodny cieniator efektu bez korzystania z pomocników dostarczonych przez D2D. Należy zachować ostrożność, aby upewnić się, że zarówno pełny shader, jak i sygnatury wejściowe funkcji eksportowania są zgodne ze specyfikacjami D2D.
Specyfikacje dla pełnych shaderów są takie same jak w wcześniejszych wersjach systemu Windows. Krótko mówiąc, parametry wejściowe cieniowania pikseli muszą być takie jak SV_POSITION, SCENE_POSITION i jeden TEXCOORD na dane wejściowe efektu.
W przypadku funkcji eksportu musi ona zwrócić typ danych float4, a jej dane wejściowe muszą być jednym z następujących typów:
Proste dane wejściowe
float4 d2d_inputN : INPUTNW przypadku prostych danych wejściowych D2D wstawi funkcję Sample między teksturą wejściową a funkcją cieniowania, albo dane wejściowe będą dostarczane przez dane wyjściowe innej funkcji cieniowania.
Złożone dane wejściowe
float4 d2d_uvN : TEXCOORDNW przypadku złożonych danych wejściowych D2D będzie przekazywać współrzędne tekstury zgodnie z opisem w dokumentacji systemu Windows 8.
Lokalizacja wyjściowa
float4 d2d_posScene : SCENE_POSITIONMożna zdefiniować tylko jedno dane wejściowe SCENE_POSITION. Ten parametr powinien być uwzględniony tylko w razie potrzeby, ponieważ tylko jedna funkcja na połączony moduł cieniowania może korzystać z tego parametru.
Semantyka musi być zdefiniowana jak powyżej, ponieważ D2D sprawdzi semantykę, aby zdecydować, jak połączyć funkcje. Jeśli jakiekolwiek dane wejściowe funkcji nie są zgodne z jednym z powyższych typów, funkcja zostanie odrzucona do łączenia cieniowania.
Tematy pokrewne
-
interfejs ID3D11Linker
-
interfejs ID3D11FunctionLinkingGraph