Udostępnij przez


Wybieranie zasobu (Direct3D 10)

Zasób to zbiór danych używanych przez pipeline 3D. Tworzenie zasobów i definiowanie ich zachowania jest pierwszym krokiem w kierunku programowania aplikacji. W tym przewodniku opisano podstawowe tematy dotyczące wybierania zasobów wymaganych przez aplikację.

Zidentyfikuj etapy rurociągu, które wymagają zasobów

Pierwszym krokiem jest wybranie etapu potoku (lub etapów), które będą korzystać z zasobu. Oznacza to, że zidentyfikuj każdy etap, który odczytuje dane z zasobu, a także etapy, które będą zapisywać dane w zasobie. Znajomość etapów potoku, w których będą używane zasoby, określa interfejsy API, które będą wywoływane w celu powiązania zasobu z etapem.

W tej tabeli wymieniono typy zasobów, które mogą być powiązane z każdym etapem potoku. Obejmuje to, czy zasób może być powiązany jako dane wejściowe lub wyjściowe, a także możliwość powiązania z interfejsem API.

Etap w potoku Wchodzenie/Wychodzenie Zasób Typ zasobu Interfejs API do wiązania
Asembler wejściowy W Bufor wierzchołka Bufor IASetVertexBuffers
Asembler wejściowy W Bufor indeksu Bufor IASetIndexBuffer
Etapy cieniowania W Shader-ResourceView Bufor, Tekstura1D, Tekstura2D, Tekstura3D VSSetShaderResources, GSSetShaderResources, PSSetShaderResources
Etapy cieniowania W bufor Shader-Constant Bufor VSSetConstantBuffers, GSSetConstantBuffers, PSSetConstantBuffers
Dane wyjściowe strumienia Na zewnątrz Bufor Bufor SOSetTargets
Fuzja danych wyjściowych Na zewnątrz Widok celu renderowania Bufor, Tekstura1D, Tekstura2D, Tekstura3D OMSetRenderTargets
Fuzja danych wyjściowych Na zewnątrz Widok głębokości/wzornika Tekstura1D, Tekstura2D OMSetRenderTargets

 

Identyfikowanie sposobu użycia poszczególnych zasobów

Po wybraniu etapów potoku, które aplikacja będzie używać (i zasobów, których będzie wymagał każdy etap), następnym krokiem jest określenie, w jaki sposób będzie używany każdy zasób, czyli czy zasób może być uzyskiwany przez CPU czy GPU.

Sprzęt, na którym działa aplikacja, będzie miał co najmniej jeden procesor CPU i jeden procesor GPU. Aby wybrać wartość użycia, rozważ, który typ procesora musi odczytywać lub zapisywać w zasobie z poniższych opcji (zobacz D3D10_USAGE).

Użycie zasobów Może zostać zaktualizowany przez Częstotliwość aktualizacji
Domyślny GPU rzadko
Dynamiczny PROCESOR często
Aranżacja GPU N/a
Niezmienialny CPU (tylko w momencie tworzenia zasobów) N/a

 

Domyślne użycie należy stosować dla zasobu, który ma być aktualizowany przez procesor rzadko (mniej niż raz na klatkę). Najlepiej, aby procesor nigdy nie zapisywał bezpośrednio do zasobu z domyślnym użyciem, aby uniknąć potencjalnych kar wydajnościowych.

Dynamiczne użycie powinno być stosowane dla zasobu, który CPU aktualizuje stosunkowo często (raz lub więcej na klatkę). Typowym scenariuszem dla zasobu dynamicznego jest utworzenie dynamicznych buforów wierzchołków i indeksów, które zostaną wypełnione w czasie wykonywania danymi o geometrii widocznej z punktu widzenia użytkownika dla każdej klatki. Te bufory będą używane do renderowania tylko tej części geometrii, która jest widoczna dla użytkownika w danej klatce.

Użycie przejściowe powinno służyć do kopiowania danych do i z innych zasobów. Typowym scenariuszem jest skopiowanie danych w zasobie z domyślnym użyciem (którego procesor CPU nie może uzyskać dostępu) do zasobu z użyciem przejściowym (do którego może uzyskać dostęp procesor CPU).

Niezmienialne zasoby powinny być używane, gdy dane w zasobie nigdy się nie zmienią.

Innym sposobem przyjrzenia się temu samemu pomysłowi jest myślenie o tym, co aplikacja robi z zasobem.

Jak aplikacja używa zasobu Użycie zasobów
Załaduj raz i nigdy nie aktualizuj Niezmienne lub domyślne
Aplikacja wielokrotnie wypełnia zasób Dynamiczny
Renderowanie na teksturę Domyślny
Dostęp CPU do danych GPU Inscenizacja

 

Jeśli nie masz pewności, jakie użycie wybrać, zacznij od domyślnego użycia, ponieważ jest to najbardziej typowy przypadek. Bufor Shader-Constant jest jednym typem zasobu, który zawsze powinien mieć domyślne użycie.

Wiązanie zasobów z etapami potoku

Zasób może być powiązany z więcej niż jednym etapem potoku jednocześnie, pod warunkiem, że spełnione są ograniczenia określone podczas jego tworzenia (flagi użycia, flagi powiązania, flagi dostępu procesora). W szczególności zasób może być powiązany jako dane wejściowe i wyjściowe jednocześnie, o ile nie można jednocześnie odczytywać i zapisywać części zasobu.

Podczas wiązania zasobu zastanów się, jak GPU i CPU będą uzyskiwać dostęp do zasobu. Zasoby zaprojektowane do jednego celu (nie używają wielu flag zastosowania, powiązania i dostępu CPU) z dużym prawdopodobieństwem skutkują lepszą wydajnością.

Rozważmy na przykład przypadek obiektu docelowego renderowania używanego wielokrotnie jako tekstura. Może być szybsze posiadanie dwóch zasobów: elementu docelowego renderowania i tekstury używanej jako zasób cieniowania. Każdy zasób używa tylko jednej flagi powiązania (D3D10_BIND_RENDER_TARGET lub D3D10_BIND_SHADER_RESOURCE). Dane zostaną skopiowane z tekstury obiektu docelowego renderowania do tekstury cieniowania przy użyciu CopyResource lub CopySubresourceRegion. Może to poprawić wydajność przez izolowanie zapisu docelowego renderowania z odczytu tekstury cieniowania. Oczywiście, jedynym sposobem, aby się upewnić, jest zaimplementowanie obu podejść i zmierzenie różnicy w wydajności w twojej konkretnej aplikacji.

Zasoby (Direct3D 10)