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.
Celem głównego podpisu w wersji 1.1 jest umożliwienie aplikacjom wskazania sterowników, gdy deskryptory w stercie deskryptora deskryptora nie zmienią się lub deskryptory danych nie zmienią się. Dzięki temu kierowcy mogą wprowadzać optymalizacje, które mogą być możliwe, wiedząc, że deskryptor lub pamięć, do której wskazuje, jest statyczna przez pewien czas.
- — omówienie
- flagi statyczne i nietrwałe
- podsumowanie interfejsu API w wersji 1.1 w wersji 1.1
- wyliczenia
- struktury
- Functions
- metod
- struktury pomocnika
- Konsekwencje naruszenia flag statyczności
- zarządzania wersjami
- Tematy pokrewne
Przegląd
Główny podpis w wersji 1.0 umożliwia zawartość stertów deskryptora i pamięci, którą wskazują na swobodną zmianę przez aplikacje w dowolnym momencie, gdy listy poleceń / pakiety odwołujące się do nich są potencjalnie w locie na procesorze GPU. Jednak bardzo często aplikacje nie potrzebują elastyczności, aby zmienić deskryptory lub pamięć po zarejestrowaniu poleceń odwołujących się do nich.
Aplikacje są często trywialnie w stanie:
- Skonfiguruj deskryptory (i możliwe, że pamięć wskazuje) przed powiązaniem tabel deskryptora lub deskryptorów głównych na liście poleceń lub pakiecie.
- Upewnij się, że te deskryptory nie zmienią się, dopóki lista poleceń /bundles odwołujące się do nich nie zakończy wykonywania po raz ostatni.
- Upewnij się, że dane wskazywane przez deskryptory nie zmieniają się przez ten sam pełny czas trwania.
Alternatywnie aplikacja może być w stanie rozpoznać, że dane nie zmieniają się przez krótszy czas. W szczególności dane mogą być statyczne dla okna w czasie podczas wykonywania listy poleceń, że powiązanie parametrów głównych (tabela deskryptora lub deskryptor główny) obecnie wskazuje dane. Innymi słowy, aplikacja może chcieć wykonać wykonywanie na osi czasu procesora GPU, która aktualizuje niektóre dane między okresami, w których jest ustawiana za pomocą parametru głównego, wiedząc, że po ustawieniu będzie statyczna.
Jeśli deskryptory lub deskryptory danych wskazują, nie zmienią się, określone sterowniki optymalizacji mogą być specyficzne dla dostawcy sprzętu i co ważne, nie zmieniają zachowania innego niż ewentualnie poprawa wydajności. Zachowanie jak największej wiedzy na temat intencji aplikacji nie obciąża aplikacji.
Jedna z optymalizacji polega na tym, że wiele sterowników może generować bardziej wydajny dostęp do pamięci przez cieniowanie, jeśli wiedzą, że obietnice aplikacji mogą dotyczyć statycznej wielkości deskryptorów i danych. Na przykład sterowniki mogą usunąć poziom pośredni na potrzeby uzyskiwania dostępu do deskryptora w stercie, konwertując go na deskryptor główny, jeśli dany sprzęt nie jest wrażliwy na rozmiar argumentu głównego.
Dodatkowym zadaniem dewelopera korzystającym z wersji 1.1 jest obietnice dotyczące zmienności i statyczności danych wszędzie tam, gdzie to możliwe, aby sterowniki mogły mieć sens optymalizacje. Deweloperzy nie muszą składać żadnych obietnic dotyczących statyczności.
Podpis główny w wersji 1.0 nadal działa bez zmian, chociaż aplikacje, które ponownie kompilują podpis główny, będą teraz domyślnie używać podpisu głównego 1.1 (z opcją wymuszenia wersji 1.0 w razie potrzeby).
Flagi statyczne i nietrwałe
Poniższe flagi są częścią podpisu głównego, aby umożliwić sterownikom wybranie strategii najlepiej obsługiwać poszczególne argumenty główne podczas ich ustawiania, a także osadzać te same założenia w obiektach stanu potoku (PSO), gdy są one pierwotnie kompilowane — ponieważ podpis główny jest częścią psO.
Następujące flagi są ustawiane przez aplikację i mają zastosowanie do deskryptorów lub danych.
typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS
{
D3D12_DESCRIPTOR_RANGE_FLAG_NONE = 0,
D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8
} D3D12_DESCRIPTOR_RANGE_FLAGS;
typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS
{
D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8
} D3D12_ROOT_DESCRIPTOR_FLAGS;
DESCRIPTORS_VOLATILE
Z tym zestawem flag deskryptorów w stercie deskryptora wskazywanym przez tabelę deskryptora głównego można zmienić przez aplikację w dowolnym momencie, z wyjątkiem czasu, gdy lista poleceń / pakiety, które wiążą tabelę deskryptora, zostały przesłane i nie zostały zakończone. Na przykład rejestrowanie listy poleceń, a następnie zmienianie deskryptorów w stercie deskryptora odnosi się do przed przesłanie listy poleceń do wykonania jest prawidłowe. Jest to jedyne obsługiwane zachowanie sygnatury głównej w wersji 1.0.
Jeśli flaga DESCRIPTORS_VOLATILE jest nie ustawiona, deskryptory są statyczne. Brak flagi dla tego trybu. Deskryptory statyczne oznaczają, że deskryptory w stercie deskryptora wskazywanym przez tabelę deskryptora głównego zostały zainicjowane przez czas ustawiania tabeli deskryptorów na liście poleceń/pakiecie (podczas nagrywania), a deskryptorzy nie mogą zostać zmienione, dopóki lista poleceń / pakiet nie zakończy wykonywania po raz ostatni. dla sygnatury głównej w wersji 1.1, deskryptory statyczne są domyślnym założeniem, a aplikacja musi w razie potrzeby określić flagę DESCRIPTORS_VOLATILE.
W przypadku pakietów korzystających z tabel deskryptorów ze statycznymi deskryptorami deskryptory muszą być gotowe od momentu zarejestrowania pakietu (w przeciwieństwie do wywołania pakietu) i nie zmieniają się do momentu zakończenia wykonywania pakietu po raz ostatni. Tabele deskryptorów wskazujących statyczne deskryptory muszą być ustawiane podczas rejestrowania pakietów i nie dziedziczone w pakiecie. Lista poleceń jest prawidłowa, aby używać tabeli deskryptorów ze statycznymi deskryptorami ustawionymi w pakiecie i zwracanymi z powrotem do listy poleceń.
Gdy deskryptory są statyczne, istnieje inna zmiana zachowania, która wymaga ustawienia flagi DESCRIPTORS_VOLATILE. Dostęp poza granicami do wszystkich widoków buforu (w przeciwieństwie do widoków Tekstury1D/2D/3D/Cube) jest nieprawidłowy i generuje niezdefiniowane wyniki, w tym możliwe resetowanie urządzenia, a nie zwracanie wartości domyślnych dla operacji odczytu lub porzucania zapisów. Celem usunięcia możliwości, aby aplikacje mogły zależeć od sprzętu poza sprawdzaniem dostępu, jest umożliwienie sterownikom wybierania podwyższania poziomu dostępu do deskryptora statycznego dostępu do deskryptora głównego, jeśli uznają to za bardziej wydajne. Deskryptory główne nie obsługują sprawdzania poza granicami.
Jeśli aplikacje zależą od bezpiecznego zachowania dostępu do pamięci podczas uzyskiwania dostępu do deskryptorów, muszą oznaczyć zakresy deskryptorów, które uzyskują dostęp do tych deskryptorów jako DESCRIPTORS_VOLATILE.
DATA_VOLATILE
W przypadku tego zestawu flag dane wskazywane przez deskryptory mogą być zmieniane przez procesor w dowolnym momencie, z wyjątkiem czasu, gdy lista poleceń / pakiety, które wiążą tabelę deskryptorów, zostały przesłane i nie zostały zakończone wykonywanie. Jest to jedyne obsługiwane zachowanie sygnatury głównej w wersji 1.0.
Flaga jest dostępna zarówno w flagach zakresu deskryptora, jak i flagach deskryptora głównego.
DATA_STATIC_WHILE_SET_AT_EXECUTE
W przypadku tego zestawu flag dane wskazywane przez deskryptory nie mogą zmieniać się od momentu ustawienia bazowego deskryptora głównego lub deskryptora na liście poleceń/pakietu podczas wykonywania na osi czasu procesora GPU, a zakończenie kolejnych losowań/dyspozytorów nie będzie już odwoływać się do danych.
Przed ustawieniem tabeli deskryptora głównego lub deskryptora na procesorze GPU te dane można zmienić nawet przez tę samą listę poleceń/pakiet. Dane można również zmienić, gdy deskryptor główny lub deskryptor wskazujący, że jest ona nadal ustawiona na liście poleceń/pakiecie, o ile nie zostały ukończone rysowanie/dyspozytory odwołujące się do niego. Jednak wymaga to ponownego odbicia tabeli deskryptora do listy poleceń przed następnym odroczeniem tabeli deskryptora głównego lub deskryptora. Dzięki temu sterownik może wiedzieć, że dane wskazywane przez deskryptor główny lub deskryptor tabeli deskryptorów uległy zmianie.
Podstawową różnicą między DATA_STATIC_WHILE_SET_AT_EXECUTE a DATA_VOLATILE jest DATA_VOLATILE sterownik nie może stwierdzić, czy kopie danych na liście poleceń zmieniły dane wskazywane przez deskryptor bez wykonywania dodatkowego śledzenia stanu. Więc jeśli na przykład sterownik może wstawić dowolne polecenia wstępnego pobierania danych do listy poleceń (aby zwiększyć wydajność cieniowania danych, na przykład), DATA_STATIC_WHILE_SET_AT_EXECUTE informuje sterownik, że musi wykonywać tylko pobieranie danych wstępnie pobieranych w tej chwili za pomocą SetGraphicsRootDescriptorTable, SetComputeRootDescriptorTable lub jednej z metod ustawiania widoku stałego buforu, widoku zasobów cieniowania lub widoku dostępu bez kolejności.
W przypadku pakietów obietnica, że dane są statyczne podczas ustawiania podczas wykonywania, są stosowane unikatowo do każdego wykonania pakietu.
Flaga jest dostępna zarówno w flagach zakresu deskryptora, jak i flagach deskryptora głównego.
DATA_STATIC
Jeśli ta flaga jest ustawiona, dane wskazywane przez deskryptory zostały zainicjowane przez czas, gdy główny deskryptor lub deskryptor tabeli odwołującej się do pamięci został ustawiony na liście poleceń / pakiecie podczas nagrywania, a dane nie mogą zostać zmienione, dopóki lista poleceń / pakiet nie zakończy wykonywania po raz ostatni.
W przypadku pakietów statyczny czas trwania rozpoczyna się od ustawienia deskryptora głównego lub deskryptora podczas rejestrowania pakietu, w przeciwieństwie do rejestrowania listy poleceń wywołujących. Ponadto tabela deskryptorów wskazująca dane statyczne musi być ustawiona w pakiecie i nie dziedziczona. Lista poleceń jest prawidłowa, aby użyć tabeli deskryptora wskazującej dane statyczne ustawione w pakiecie i zwrócone z powrotem do listy poleceń.
Flaga jest dostępna zarówno w flagach zakresu deskryptora, jak i flagach deskryptora głównego.
Łączenie flag
W danym momencie można określić co najwyżej jedną flagę DANYCH, z wyjątkiem zakresów deskryptora sampler, które w ogóle nie obsługują flag DANYCH, ponieważ próbkatory nie wskazują danych.
Brak flag DANYCH dla zakresów deskryptorów SRV i CBV oznacza, że przyjmuje się domyślne zachowanie DATA_STATIC_WHILE_SET_AT_EXECUTE. Przyczyną wybrania tej wartości domyślnej zamiast DATA_STATIC jest to, że DATA_STATIC_WHILE_SET_AT_EXECUTE jest znacznie bardziej prawdopodobne, aby być bezpiecznym ustawieniem domyślnym dla większości przypadków, jednocześnie zapewniając lepszą szansę optymalizacji niż domyślne DATA_VOLATILE.
Brak flag DANYCH dla zakresów deskryptorów UAV oznacza, że przyjmuje się domyślne zachowanie DATA_VOLATILE, biorąc pod uwagę, że zazwyczaj są zapisywane widoki UAV.
DESCRIPTORS_VOLATILE nie można połączyć z DATA_STATIC, ale można połączyć z innymi flagami DANYCH. Przyczyną, DESCRIPTORS_VOLATILE można połączyć z DATA_STATIC_WHILE_SET_AT_EXECUTE jest to, że deskryptory lotne nadal wymagają, aby deskryptory mogły być gotowe podczas wykonywania listy poleceń/pakietów, a DATA_STATIC_WHILE_SET_AT_EXECUTE tylko obiecuje statyczność w podzestawie listy poleceń / wykonywania pakietu.
Flaga — podsumowanie
W poniższych tabelach podsumowano kombinacje flag, które mogą być stosowane.
| Prawidłowe ustawienia D3D12_DESCRIPTOR_RANGE_FLAGS | Opis |
|---|---|
| Brak ustawionych flag | Deskryptory są statyczne (wartość domyślna). Domyślne założenia dotyczące danych: dla SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE i UAV: DATA_VOLATILE. Te wartości domyślne dla SRV/CBV bezpiecznie pasują do wzorców użycia dla większości podpisów głównych. |
| DATA_STATIC | Deskryptory i dane są statyczne. Pozwala to zmaksymalizować potencjał optymalizacji czynników. |
| DATA_VOLATILE | Deskryptory są statyczne i dane są nietrwałe. |
| DATA_STATIC_WHILE_SET_AT_EXECUTE | Deskryptory są statyczne, a dane są statyczne podczas ustawiania podczas wykonywania. |
| DESCRIPTORS_VOLATILE | Deskryptory są nietrwałe, a domyślne założenia dotyczą danych: dla SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE i UAV: DATA_VOLATILE. |
| DESCRIPTORS_VOLATILE | DATA_VOLATILE | Deskryptory i dane są nietrwałe, co odpowiada głównej podpisowi 1.0. |
| DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE | Deskryptory są nietrwałe, ale pamiętaj, że nadal nie zezwalają na ich zmianę podczas wykonywania listy poleceń. Dlatego ważne jest połączenie dodatkowej deklaracji, że dane są statyczne podczas ustawiania za pomocą tabeli deskryptora głównego podczas wykonywania — bazowe deskryptory są skutecznie statyczne przez dłuższy czas niż dane są obiecane jako statyczne. |
| Prawidłowe ustawienia D3D12_ROOT_DESCRIPTOR_FLAGS | Opis |
|---|---|
| Brak ustawionych flag | Domyślne założenia dotyczące danych: dla SRV/CBV: DATA_STATIC_WHILE_SET_AT_EXECUTE i UAV: DATA_VOLATILE. Te wartości domyślne dla SRV/CBV bezpiecznie pasują do wzorców użycia dla większości podpisów głównych. |
| DATA_STATIC | Dane są statyczne, co jest najlepszym potencjałem optymalizacji czynników. |
| DATA_STATIC_WHILE_SET_AT_EXECUTE | Dane są statyczne podczas ustawiania podczas wykonywania. |
| DATA_VOLATILE | Odpowiednik podpisu głównego 1.0. |
Podsumowanie interfejsu API w wersji 1.1
Następujące wywołania interfejsu API umożliwiają włączenie wersji 1.1.
Wyliczenia
Te wyliczenia zawierają flagi klucza umożliwiające określenie deskryptora i zmienności danych.
- D3D_ROOT_SIGNATURE_VERSION: identyfikatory wersji.
- D3D12_DESCRIPTOR_RANGE_FLAGS : zakres flag określający, czy deskryptory, czy dane są nietrwałe, czy statyczne.
- D3D12_ROOT_DESCRIPTOR_FLAGS : podobny zakres flag do D3D12_DESCRIPTOR_RANGE_FLAGS, z tą różnicą, że tylko flagi danych dotyczą deskryptorów głównych.
Struktur
Zaktualizowane struktury (z wersji 1.0) zawierają odwołania do flag zmienności/statycznych.
D3D12_FEATURE_DATA_ROOT_SIGNATURE: przekaż tę strukturę do CheckFeatureSupport, aby sprawdzić obsługę głównej sygnatury w wersji 1.1.
D3D12_VERSIONED_ROOT_SIGNATURE_DESC : może przechowywać dowolną wersję opisu podpisu głównego i jest przeznaczony do użycia z funkcjami serializacji/deserializacji wymienionych poniżej.
Te struktury są równoważne tym używanym w wersji 1.0, a dodanie nowych pól flag dla zakresów deskryptorów i deskryptorów głównych:
Funkcje
Metody wymienione tutaj zastępują oryginalne funkcje D3D12SerializeRootSignature i D3D12CreateRootSignatureDeserializer, ponieważ są one przeznaczone do pracy z dowolną wersją podpisu głównego. Zserializowany formularz jest przekazywany do interfejsu API CreateRootSignature. Jeśli cieniowanie zostało utworzone z podpisem głównym, skompilowany cieniowanie będzie zawierać już zserializowany podpis główny.
- D3D12SerializeVersionedRootSignature: jeśli aplikacja proceduralnie wygeneruje strukturę danych D3D12_VERSIONED_ROOT_SIGNATURE, musi utworzyć postać serializowaną przy użyciu tej funkcji.
- D3D12CreateVersionedRootSignatureDeserializer : generuje interfejs, który może zwrócić deserializowaną strukturę danych za pośrednictwem GetUnconvertedRootSignatureDesc.
Metody
Interfejs ID3D12VersionedRootSignatureDeserializer jest tworzony w celu deserializacji struktury danych sygnatury głównej.
- GetRootSignatureDescAtVersion : konwertuje struktury opisu podpisu głównego na żądaną wersję.
- GetUnconvertedRootSignatureDesc : zwraca wskaźnik do struktury D3D12_VERSIONED_ROOT_SIGNATURE_DESC.
Struktury pomocnika
Struktury pomocnika zostały dodane do pomocy w inicjowaniu niektórych struktur w wersji 1.1.
- CD3DX12_DESCRIPTOR_RANGE1
- CD3DX12_ROOT_PARAMETER1
- CD3DX12_STATIC_SAMPLER1
- CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC
Zapoznaj się z tematem Struktury pomocnika i funkcje dla D3D12.
Konsekwencje naruszenia flag statycznych
Deskryptor i flagi danych opisane powyżej (a także wartości domyślne implikowane przez brak określonych flag) definiują obietnicę przez aplikację do sterownika o tym, jak będzie się zachowywać. Jeśli aplikacja narusza obietnicę, jest to nieprawidłowe zachowanie: wyniki są niezdefiniowane i mogą się różnić w różnych sterownikach i sprzęcie.
Warstwa debugowania ma opcje weryfikacji, że aplikacje przestrzegają swoich obietnic, w tym domyślne obietnice, które są dostarczane z użyciem podpisu głównego w wersji 1.1 bez ustawiania żadnych flag.
Zarządzanie wersjami
Podczas kompilowania podpisów głównych dołączonych do cieniowania nowsze kompilatory HLSL będą domyślnie kompilować podpis główny w wersji 1.1, natomiast stare kompilatory HLSL obsługują tylko 1.0. Należy pamiętać, że podpisy główne 1.1 nie będą działać w systemach operacyjnych, które nie obsługują podpisu głównego 1.1.
Wersja podpisu głównego skompilowana za pomocą cieniowania może być zmuszona do określonej wersji przy użyciu /force_rootsig_ver <version>. Wymuszenie wersji powiedzie się, jeśli kompilator może zachować zachowanie podpisu głównego kompilowanego w wersji wymuszonej, na przykład porzucając nieobsługiwane flagi w podpisie głównym, które służą tylko do celów optymalizacji, ale nie mają wpływu na zachowanie.
Dzięki temu aplikacja może na przykład skompilować podpis główny 1.1 do wersji 1.0 i 1.1 podczas kompilowania aplikacji i wybrać odpowiednią wersję w środowisku uruchomieniowym w zależności od poziomu obsługi systemu operacyjnego. Najbardziej wydajne byłoby jednak, aby aplikacja kompilować podpisy główne indywidualnie (szczególnie w przypadku potrzeby wielu wersji), oddzielnie od cieniowania. Nawet jeśli moduły cieniowania nie są początkowo kompilowane z dołączonym podpisem głównym, można zachować korzyść weryfikacji podpisu głównego przez kompilator przy użyciu opcji kompilatora /verifyrootsignature. Później w czasie wykonywania można utworzyć obiekty PSO przy użyciu cieniowania, które nie mają w nich podpisów głównych podczas przekazywania żądanego podpisu głównego (być może odpowiedniej wersji obsługiwanej przez system operacyjny) jako oddzielnego parametru.
Tematy pokrewne
-
tworzenie sygnatury głównej