Udostępnij za pośrednictwem


Ważne zmiany z Direct3D 11 do Direct3D 12

Direct3D 12 reprezentuje znaczące odejście od modelu programowania Direct3D 11. Funkcja Direct3D 12 umożliwia aplikacjom zbliżenie się do sprzętu niż kiedykolwiek wcześniej. Dzięki bliżej sprzętu funkcja Direct3D 12 jest szybsza i wydajniejsza. Jednak kompromis aplikacji o zwiększonej szybkości i wydajności z direct3D 12 polega na tym, że odpowiadasz za więcej zadań niż w przypadku direct3D 11.

Direct3D 12 to powrót do programowania niskiego poziomu; zapewnia większą kontrolę nad elementami graficznymi gier i aplikacji, wprowadzając następujące nowe funkcje: obiekty reprezentujące ogólny stan potoku, listy poleceń i pakiety do przesyłania pracy oraz stertę deskryptora i tabele na potrzeby dostępu do zasobów.

Twoja aplikacja zwiększyła szybkość i wydajność dzięki funkcji Direct3D 12, ale odpowiadasz za więcej zadań niż w przypadku usługi Direct3D 11.

Jawna synchronizacja

  • W wersji Direct3D 12 synchronizacja CPU-GPU jest teraz jawną odpowiedzialnością aplikacji i nie jest już niejawnie wykonywana przez środowisko uruchomieniowe, ponieważ jest w trybie Direct3D 11. Oznacza to również, że żadne automatyczne sprawdzanie zagrożeń potoku nie jest wykonywane przez direct3D 12, więc ponownie jest to odpowiedzialność za aplikacje.
  • W wersji Direct3D 12 aplikacje są odpowiedzialne za potokowe aktualizacje danych. Oznacza to, że wzorzec "Map/Lock-DISCARD" w trybie Direct3D 11 musi być wykonywany ręcznie w trybie Direct3D 12. W trybie Direct3D 11, jeśli procesor GPU nadal używa buforu podczas wywoływania ID3D11DeviceContext::Map z D3D11_MAP_WRITE_DISCARD, środowisko uruchomieniowe zwraca wskaźnik do nowego regionu pamięci zamiast starych danych buforu. Dzięki temu procesor GPU będzie nadal korzystać ze starych danych, gdy aplikacja umieszcza dane w nowym buforze. W aplikacji nie jest wymagane żadne dodatkowe zarządzanie pamięcią; stary bufor jest ponownie używany lub niszczony automatycznie po zakończeniu pracy z procesorem GPU.
  • W wersji Direct3D 12 wszystkie aktualizacje dynamiczne (w tym stałe, dynamiczne wierzchołków, tekstury dynamiczne itd.) są jawnie kontrolowane przez aplikację. Te aktualizacje dynamiczne obejmują wszelkie wymagane ogrodzenia procesora GPU lub buforowanie. Aplikacja jest odpowiedzialna za przechowywanie dostępnej pamięci, dopóki nie będzie już potrzebna.
  • Funkcja Direct3D 12 używa zliczania odwołań w stylu MODELU COM tylko dla okresów istnienia interfejsów (przy użyciu słabego modelu referencyjnego Direct3D powiązanego z okresem istnienia urządzenia). Wszystkie okresy istnienia zasobów i opisów są jedynym odpowiedzialnym okresem istnienia aplikacji w celu zachowania przez odpowiedni czas trwania i nie są zliczane odwołania. Funkcja Direct3D 11 używa zliczania odwołań do zarządzania okresami istnienia zależności interfejsu.

Zarządzanie miejscem przechowywania pamięci fizycznej

Aplikacja Direct3D 12 musi zapobiegać warunkom wyścigu między wieloma kolejkami, wieloma kartami i wątkami procesora CPU. D3D12 nie synchronizuje już procesora CPU i procesora GPU ani nie obsługuje wygodnych mechanizmów zmiany nazw zasobów lub buforowania wielobuforowego. Ogrodzenia muszą służyć do uniknięcia wielu jednostek przetwarzania przed nadmiernym zapisem pamięci przed zakończeniem korzystania z niej przez inną jednostkę przetwarzania.

Aplikacja Direct3D 12 musi zapewnić, że dane są w pamięci, podczas gdy procesor GPU je odczytuje. Pamięć używana przez każdy obiekt jest rezydentem podczas tworzenia obiektu. Aplikacje wywołujące te metody muszą używać ogrodzeń, aby upewnić się, że procesor GPU nie uzyskuje dostępu do obiektów, które zostały eksmitowane.

Bariery zasobów to inny wymagany typ synchronizacji, używany do synchronizowania przejść zasobów i podźródła na bardzo szczegółowym poziomie.

Zapoznaj się z artykułem Zarządzanie pamięcią wDirect3D 12.

Obiekty stanu potoku

Funkcja Direct3D 11 umożliwia manipulowanie stanem potoku za pośrednictwem dużego zestawu niezależnych obiektów. Na przykład stan asemblera wejściowego, stan cieniowania pikseli, stan rasteryzatora i stan połączenia wyjściowego można modyfikować niezależnie. Ten projekt zapewnia wygodną i stosunkowo wysoką reprezentację potoku grafiki, ale nie wykorzystuje możliwości nowoczesnego sprzętu, przede wszystkim dlatego, że różne stany są często współzależne. Na przykład wiele procesorów GPU łączy cieniowanie pikseli i stan połączenia wyjściowego w jedną reprezentację sprzętu. Jednak ze względu na to, że interfejs API Direct3D 11 umożliwia oddzielne ustawianie tych etapów potoku, sterownik wyświetlania nie może rozwiązać problemów ze stanem potoku, dopóki stan nie zostanie sfinalizowany, co nie nastąpi do czasu rysowania. Ten schemat opóźnia konfigurację stanu sprzętu, co oznacza dodatkowe obciążenie i mniej maksymalnych wywołań rysowania na ramkę.

Direct3D 12 adresuje ten schemat przez ujednolicenie większości stanu potoku do niezmiennych obiektów stanu potoku (PSO), które są finalizowane podczas tworzenia. Sprzęt i sterowniki mogą następnie natychmiast konwertować pso na wszelkie instrukcje i stan sprzętu są wymagane do wykonania pracy procesora GPU. Nadal można dynamicznie zmieniać, które pso jest używane, ale w tym celu sprzęt musi tylko skopiować minimalną ilość wstępnie obliczonego stanu bezpośrednio do rejestrów sprzętu, zamiast obliczać stan sprzętu na bieżąco. Przy użyciu obiektów PSO obciążenie wywołania rysowania jest znacznie mniejsze, a wiele innych wywołań rysowania może wystąpić na ramkę. Aby uzyskać więcej informacji na temat obiektów PSO, zobacz Zarządzanie stanem potoku grafiki w trybie Direct3D 12.

Listy poleceń i pakiety

W wersji Direct3D 11 wszystkie przesyłanie pracy odbywa się za pośrednictwem bezpośredniego kontekstu, który reprezentuje pojedynczy strumień poleceń, które przechodzą do procesora GPU. Aby osiągnąć wielowątkowy skalowanie, gry mają również konteksty odroczone dostępne dla nich. Konteksty odroczone w wersji Direct3D 11 nie są mapowane idealnie na sprzęt, więc w nich można wykonać stosunkowo małą pracę.

Direct3D 12 wprowadza nowy model do przesyłania pracy na podstawie list poleceń, które zawierają całe informacje potrzebne do wykonania określonego obciążenia na procesorze GPU. Każda nowa lista poleceń zawiera informacje, takie jak, które pso ma być używane, jakie zasoby tekstury i buforu są potrzebne, oraz argumenty do wszystkich wywołań rysowania. Ponieważ każda lista poleceń jest samodzielna i nie dziedziczy stanu, sterownik może wstępnie obliczyć wszystkie niezbędne polecenia procesora GPU z góry i w sposób wolny wątkowy. Jedynym wymaganym procesem seryjnym jest ostateczne przesłanie list poleceń do procesora GPU za pośrednictwem kolejki poleceń.

Oprócz list poleceń, Direct3D 12 wprowadza również drugi poziom wstępnego obliczania pracy: pakietów. W przeciwieństwie do list poleceń, które są całkowicie samodzielne i są zwykle konstruowane, przesyłane raz i odrzucane, pakiety zapewniają formę dziedziczenia stanu, które zezwalają na ponowne użycie. Jeśli na przykład gra chce narysować dwa modele znaków z różnymi teksturami, jednym z podejść jest zarejestrowanie listy poleceń z dwoma zestawami identycznych wywołań rysowania. Jednak innym podejściem jest "rejestrowanie" jednego pakietu, który rysuje pojedynczy model znaków, a następnie "odtwórz" pakiet dwa razy na liście poleceń przy użyciu różnych zasobów. W tym drugim przypadku sterownik wyświetlania musi tylko obliczyć odpowiednie instrukcje raz, a utworzenie listy poleceń zasadniczo oznacza dwa wywołania funkcji o niskich kosztach.

Aby uzyskać więcej informacji na temat list poleceń i pakietów, zobacz przesyłanie pracy w trybie Direct3D 12.

Stertę deskryptora i tabele

Powiązanie zasobów w wersji Direct3D 11 jest wysoce abstrakcyjne i wygodne, ale pozostawia wiele nowoczesnych możliwości sprzętowych, które nie są wykorzystywane. W wersji Direct3D 11 gry tworzą widoku obiektów zasobów, a następnie wiążą te widoki z kilkoma gniazdami na różnych etapach cieniowania w potoku. Cieniowanie z kolei odczytuje dane z tych jawnych miejsc powiązania, które są stałe w czasie rysowania. Ten model oznacza, że za każdym razem, gdy gra będzie rysować przy użyciu różnych zasobów, musi ponownie powiązać różne widoki z różnymi miejscami i wywołać losowanie ponownie. Ten przypadek reprezentuje również obciążenie, które można wyeliminować przez pełne wykorzystanie nowoczesnych możliwości sprzętowych.

Funkcja Direct3D 12 zmienia model powiązania tak, aby był zgodny z nowoczesnym sprzętem i znacznie poprawia wydajność. Zamiast wymagać autonomicznych widoków zasobów i jawnego mapowania na miejsca, direct3D 12 zapewnia stertę deskryptora, w której gry tworzą różne widoki zasobów. Ten schemat zapewnia mechanizm procesora GPU umożliwiający bezpośrednie zapisanie opisu zasobów sprzętowych (deskryptora) w pamięci z góry. Aby zadeklarować, które zasoby mają być używane przez potok dla określonego wywołania rysowania, gry określają co najmniej jedną tabelę deskryptora reprezentującą zakresy podrzędne pełnego sterta deskryptora. Ponieważ sterta deskryptora została już wypełniona odpowiednimi danymi deskryptora specyficznymi dla sprzętu, zmiana tabel deskryptorów jest niezwykle tanią operacją.

Oprócz ulepszonej wydajności oferowanej przez stertę deskryptora i tabele, direct3D 12 umożliwia również dynamiczne indeksowanie zasobów w cieniowaniach, co zapewnia bezprecedensową elastyczność i odblokowywanie nowych technik renderowania. Na przykład nowoczesne aparaty renderowania odroczonego zwykle koduje identyfikator materiału lub obiektu pewnego rodzaju do pośredniego buforu g. W wersji Direct3D 11 silniki te muszą być ostrożne, aby uniknąć używania zbyt wielu materiałów, ponieważ w tym zbyt wiele w jednym buforze g może znacznie spowolnić końcowy przepustek renderowania. W przypadku dynamicznie indeksowanych zasobów scena z tysiącami materiałów może zostać sfinalizowana tak szybko, jak jedna z zaledwie dziesięcioma.

Aby uzyskać więcej informacji na temat stertów deskryptora i tabel, zobacz powiązanie zasobówi Różnice w modelu powiązań z wersji Direct3D 11.

Przenoszenie z direct3D 11

Przenoszenie z direct3D 11 jest procesem zaangażowanym, opisanym w Przenoszenie z direct3D 11 do Direct3D 12. Zapoznaj się również z zakresem opcji w Praca z direct3D 11, Direct3D 10 i Direct2D.

Understanding Direct3D 12