Bufory indeksów (Direct3D 9)
Bufory indeksów, reprezentowane przez interfejs IDirect3DIndexBuffer9, są pamięciami zawierającymi dane indeksów. Dane indeksów, lub indeksy, to przesunięcia liczb całkowitych w buforach wierzchołków i są używane do renderowania prymitywów przy użyciu metody IDirect3DDevice9::DrawIndexedPrimitive.
Bufor wierzchołków zawiera wierzchołki; dlatego można narysować bufor wierzchołków z indeksowanymi prymitywami lub bez nich. Jednak ponieważ bufor indeksu zawiera indeksy, nie można użyć buforu indeksu bez odpowiedniego buforu wierzchołka. Na marginesie, IDirect3DDevice9::DrawIndexedPrimitiveUP i IDirect3DDevice9::DrawPrimitiveUP to jedyne metody wywołania rysowania bez użycia indeksu lub bufora wierzchołka.
Opis buforu indeksacji
Bufor indeksu jest opisany pod względem jego możliwości, takich jak miejsce, w którym istnieje w pamięci, czy obsługuje odczyt i zapis, oraz typ i liczbę indeksów, które może zawierać. Te cechy są przechowywane w strukturze D3DINDEXBUFFER_DESC.
Opisy indeksów informują aplikację o tym, jak został utworzony istniejący bufor. Należy podać pustą strukturę opisu, aby system mógł ją wypełnić możliwościami wcześniej utworzonego buforu indeksu.
- Pole Format opisuje format danych buforu indeksu.
- Typ identyfikuje typ zasobu buforu indeksu.
- Członek struktury użycia zawiera ogólne flagi zdolności. Flaga D3DUSAGE_SOFTWAREPROCESSING wskazuje, że bufor indeksu ma być używany z przetwarzaniem wierzchołków oprogramowania. Obecność flagi D3DUSAGE_WRITEONLY w obszarze Użycie wskazuje, że pamięć buforu indeksu jest używana tylko dla operacji zapisu. Dzięki temu sterownik może umieścić dane indeksu w najlepszej lokalizacji pamięci, aby umożliwić szybkie przetwarzanie i renderowanie. Jeśli flaga D3DUSAGE_WRITEONLY nie jest używana, istnieje mniejsze prawdopodobieństwo, że sterownik umieści dane w miejscu nieefektywnym dla operacji odczytu. To poświęca pewną szybkość przetwarzania i renderowania. Jeśli ta flaga nie jest określona, zakłada się, że aplikacje wykonują operacje odczytu i zapisu na danych w buforze indeksu.
- Pula określa klasę pamięci przydzieloną dla buforu indeksu. Flaga D3DPOOL_SYSTEMMEM wskazuje, że system utworzył bufor indeksu w pamięci systemowej.
- Członek Rozmiar przechowuje rozmiar danych buforu wierzchołka w bajtach.
- Ostatni parametr pSharedHandle nie jest używany. Ustaw ją na wartość null.
Wymagania dotyczące przetwarzania indeksów
Wydajność operacji przetwarzania indeksu zależy w dużym stopniu od tego, gdzie znajduje się bufor indeksu w pamięci i jakiego typu urządzenie renderowania jest używane. Aplikacje kontrolują alokację pamięci dla buforów indeksów w momencie ich tworzenia. Po ustawieniu flagi pamięci D3DPOOL_SYSTEMMEM bufor indeksu jest tworzony w pamięci systemowej. Gdy jest używana flaga pamięci D3DPOOL_DEFAULT, sterownik urządzenia określa, gdzie pamięć buforu indeksu jest najlepiej przydzielona, często określana jako optymalna pamięć sterownika. Optymalna pamięć sterownika może być lokalną pamięcią wideo, pamięcią nielokacyjną lub pamięcią systemową.
Metoda określa, że ustawienie flagi zachowania D3DUSAGE_SOFTWAREPROCESSING podczas wywoływania IDirect3DDevice9::CreateIndexBuffer oznacza, że bufor indeksu ma być używany z przetwarzaniem wierzchołków za pomocą oprogramowania. Ta flaga jest wymagana w przetwarzaniu wierzchołków w trybie mieszanym (D3DCREATE_MIXED_VERTEXPROCESSING), gdy jest używane przetwarzanie wierzchołków za pomocą oprogramowania.
Aplikacja może bezpośrednio zapisywać indeksy w buforze indeksu przydzielonym w pamięci optymalnej dla sterownika. Ta technika uniemożliwia później nadmiarową operację kopiowania. Ta technika nie działa prawidłowo, jeśli aplikacja odczytuje dane z buforu indeksu, ponieważ operacje odczytu wykonywane przez hosta z pamięci optymalnej dla sterownika mogą być bardzo powolne. W związku z tym, jeśli aplikacja musi odczytywać dane podczas przetwarzania albo zapisywać dane w buforze w sposób nierównomierny, bufor indeksu pamięci systemowej jest lepszym wyborem.
Notatka
Zawsze używaj D3DPOOL_DEFAULT, chyba że chcesz uniknąć korzystania z pamięci wideo lub potrzebujesz dużych ilości pamięci RAM zablokowanej stroną, gdy sterownik umieszcza bufory wierzchołków lub indeksów w pamięci AGP.
Tworzenie buforu indeksu
Utwórz obiekt buforu indeksu, wywołując metodę IDirect3DDevice9::CreateIndexBuffer, która akceptuje sześć parametrów.
Pierwszy parametr określa długość buforu indeksu w bajtach.
Drugi parametr to zestaw kontrolek użycia. Między innymi jego wartość określa, czy wierzchołki, do których odnoszą się indeksy, mogą zawierać informacje o przycięciu. Aby zwiększyć wydajność, określ D3DUSAGE_DONOTCLIP, gdy przycinanie nie jest wymagane.
Flaga D3DUSAGE_SOFTWAREPROCESSING można ustawić, gdy dla takiego urządzenia jest włączone mieszane lub programowe przetwarzanie wierzchołków (D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING). D3DUSAGE_SOFTWAREPROCESSING należy ustawić, aby bufory były używane z przetwarzaniem wierzchołków oprogramowania w trybie mieszanym, ale nie należy go ustawiać dla uzyskania najlepszej możliwej wydajności podczas korzystania z przetwarzania indeksów sprzętowych w trybie mieszanym (D3DCREATE_HARDWARE_VERTEXPROCESSING). Jednak ustawienie D3DUSAGE_SOFTWAREPROCESSING jest jedyną opcją, gdy pojedynczy bufor jest używany zarówno z przetwarzaniem sprzętowym, jak i przetwarzaniem wierzchołków przez oprogramowanie. D3DUSAGE_SOFTWAREPROCESSING jest dozwolone w przypadku urządzeń mieszanych i programowych.
Istnieje możliwość wymuszenia przeniesienia buforów wierzchołków i indeksów do pamięci systemowej poprzez określenie D3DPOOL_SYSTEMMEM, nawet gdy przetwarzanie indeksów odbywa się sprzętowo. Jest to sposób, aby uniknąć nadmiernie dużych ilości pamięci zablokowanej stroną, gdy sterownik umieszcza te bufory w pamięci AGP.
Trzeci parametr to element D3DFMT_INDEX16 lub D3DFMT_INDEX32 typu wyliczeniowego D3DFORMAT, który określa rozmiar każdego indeksu.
Czwarty parametr jest elementem wyliczanego typu D3DPOOL, który informuje system, gdzie umieścić nowy bufor indeksu w pamięci.
Ostatnim parametrem, który IDirect3DDevice9::CreateIndexBuffer akceptuje, jest adres zmiennej wypełnionej wskaźnikiem do nowego IDirect3DIndexBuffer9 interfejsu buforu wierzchołka, jeśli wywołanie powiedzie się.
Poniższy przykład kodu C++ pokazuje, jak może wyglądać tworzenie buforu indeksu w kodzie.
/*
* For the purposes of this example, the d3dDevice variable is the
* address of an IDirect3DDevice9 interface exposed by a
* Direct3DDevice object, g_IB is a variable of type
* LPDIRECT3DINDEXBUFFER9.
*/
if( FAILED( d3dDevice->CreateIndexBuffer( 16384 *sizeof(WORD),
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT,
&g_IB, NULL ) ) )
return E_FAIL;
Uzyskiwanie dostępu do buforu indeksu
Obiekty buforu indeksu umożliwiają aplikacjom bezpośredni dostęp do pamięci przydzielonej dla danych indeksu. Wskaźnik do pamięci buforu indeksu można pobrać, wywołując metodę IDirect3DIndexBuffer9::Lock, a następnie uzyskać dostęp do pamięci zgodnie z potrzebami, aby wypełnić bufor nowymi danymi indeksu lub odczytać wszystkie zawarte w nim dane. Metoda Lock akceptuje cztery parametry. Pierwszy, OffsetToLock, to przesunięcie w danych indeksu. Drugi parametr to rozmiar mierzony w bajtach danych indeksu. Trzeci parametr akceptowany przez metodę IDirect3DIndexBuffer9::Lock, ppbData, to adres wskaźnika typu BYTE, który zostaje wypełniony wskaźnikiem do danych indeksu, jeśli wywołanie się powiedzie.
Ostatni parametr, Flags, informuje system, jak pamięć powinna być zablokowana. Można go użyć, aby wskazać, w jaki sposób aplikacja uzyskuje dostęp do danych w buforze. Określ stałe dla parametru Flags zgodnie ze sposobem uzyskiwania dostępu do danych indeksu przez aplikację. Dzięki temu sterownik może zablokować pamięć i zapewnić najlepszą wydajność, biorąc pod uwagę żądany typ dostępu. Użyj flagi D3DLOCK_READONLY, jeśli Twoja aplikacja będzie odczytywać tylko z bufora indeksowego. Włączenie tej flagi umożliwia direct3D zoptymalizowanie swoich procedur wewnętrznych w celu poprawy wydajności, biorąc pod uwagę, że dostęp do pamięci będzie tylko do odczytu.
Po wypełnieniu lub odczytaniu danych indeksu wywołaj metodę IDirect3DIndexBuffer9::Unlock, jak pokazano w poniższym przykładzie kodu.
// This code example assumes the m_pIndexBuffer is a variable of type
// LPDIRECT3DINDEXBUFFER9 and that g_Indices has been properly
// initialized with indices.
// To fill the index buffer, you must lock the buffer to gain
// access to the indices. This mechanism is required because index
// buffers may be in device memory.
VOID* pIndices;
if( FAILED( m_pIndexBuffer->Lock(
0, // Fill from start of the buffer
sizeof(g_Indices), // Size of the data to load
BYTE**)&pIndices, // Returned index data
0 ) ) ) // Send default flags to the lock
{
SAFE_RELEASE(m_pIndexBuffer);
return E_FAIL;
}
memcpy( pIndices, g_Indices, sizeof(g_Indices) );
m_pIndexBuffer->Unlock();
Notatka
Jeśli tworzysz bufor indeksu z flagą D3DUSAGE_WRITEONLY, nie używaj flagi blokowania D3DLOCK_READONLY. Użyj flagi D3DLOCK_READONLY, jeśli aplikacja będzie tylko czytać z pamięci bufora indeksu. Włączenie tej flagi umożliwia direct3D zoptymalizowanie swoich procedur wewnętrznych w celu poprawy wydajności, biorąc pod uwagę, że dostęp do pamięci będzie tylko do odczytu.
Aby uzyskać informacje na temat używania D3DLOCK_DISCARD lub D3DLOCK_NOOVERWRITE dla parametru Flags metody IDirect3DIndexBuffer9::Lock, zobacz Performance Optimizations (Direct3D 9).
W języku C++, ponieważ uzyskujesz bezpośredni dostęp do pamięci przydzielonej dla buforu indeksu, upewnij się, że aplikacja prawidłowo uzyskuje dostęp do przydzielonej pamięci. W przeciwnym razie ryzykujesz, że renderowanie tej pamięci jest nieprawidłowe. Użyj kroku formatu indeksu, który stosuje twoja aplikacja, aby przejść z jednego indeksu w przydzielonym buforze do innego.
Pobierz informacje o buforze indeksu, wywołując metodę IDirect3DIndexBuffer9::GetDesc. Ta metoda wypełnia członków struktury D3DINDEXBUFFER_DESC informacjami dotyczącymi bufora indeksu.
Tematy pokrewne
-
Zasoby Direct3D