Indexpuffer (Direct3D 9)

Bei Indexpuffern, dargestellt durch die IDirect3DIndexBuffer9-Schnittstelle, handelt es sich um Arbeitsspeicherpuffer mit Indexdaten. Indexdaten oder Indizes sind ganzzahlige Offsets in Vertexpuffern und werden zum Rendern von Primitiven mithilfe der IDirect3DDevice9::DrawIndexedPrimitive-Methode verwendet.

Ein Vertexpuffer enthält Scheitelpunkte; deshalb können Sie einen Vertexpuffer mit oder ohne indizierten Grundtypen zeichnen. Da ein Indexpuffer jedoch Indizes enthält, können Sie einen Indexpuffer nicht ohne entsprechenden Vertexpuffer verwenden. (Nebenbei bemerkt sind IDirect3DDevice9::D rawIndexedPrimitiveUP und IDirect3DDevice9::D rawPrimitiveUP die einzigen Zeichenmethoden, die ohne Index oder Vertexpuffer zeichnen.)

Beschreibung des Indexpuffers

Ein Indexpuffer wird anhand seiner Fähigkeiten beschrieben, wie z. B. wo im Speicher er vorhanden ist, ob Lese- und Schreibberechtigungen unterstützt werden, und nach Typ und Anzahl der enthaltenen Indizes. Diese Merkmale werden in einer D3DINDEXBUFFER_DESC-Struktur gespeichert.

Die Beschreibungen von Indexpuffern geben Ihrer Anwendung Hinweise darauf, wie ein vorhandener Puffer erstellt wurde. Sie stellen eine leere Beschreibungsstruktur für das System bereit, die mit den Fähigkeiten eines vorher erstellten Indexpuffers gefüllt wird.

  • Der Member „Format“ beschreibt das Oberflächenformat der Indexpufferdaten.
  • Der Typ identifiziert den Ressourcentyp des Indexpuffers.
  • Der Strukturmember „Usage“ enthält allgemeine Funktionsflags. Das Flag „D3DUSAGE_SOFTWAREPROCESSING“ gibt an, dass der Indexpuffer zusammen mit der Softwarevertexverarbeitung verwendet werden soll. Das Vorhandensein des Flags „D3DUSAGE_WRITEONLY“ in „Usage“ gibt an, dass der Indexpufferspeicher nur für Schreibvorgänge verwendet wird. Dadurch kann der Treiber die Indexdaten am günstigsten Arbeitsspeicherort ablegen und so eine schnelle Verarbeitung und schnelles Rendering ermöglichen. Wenn das Flag „D3DUSAGE_WRITEONLY“ nicht verwendet wird, ist die Wahrscheinlichkeit geringer, dass der Treiber die Daten an einem für Lesevorgänge ungünstigen Speicherort ablegt. Hierdurch werden Verarbeitungs- und Renderinggeschwindigkeit beeinträchtigt. Wird dieses Flag nicht angegeben, wird davon ausgegangen, dass Anwendungen Lese- und Schreibvorgänge für die Daten im Indexpuffer ausführen.
  • Der Pool gibt die dem Indexpuffer zugewiesene Arbeitsspeicherklasse an. Das Flag „D3DPOOL_SYSTEMMEM“ gibt an, dass das System den Indexpuffer im Systemarbeitsspeicher erstellt hat.
  • Der Member „Size“ speichert die Größe der Vertexpufferdaten in Bytes.
  • Der letzte Parameter „pSharedHandle“ wird nicht verwendet. Legen Sie ihn auf NULL fest.

Indexverarbeitungsanforderungen

Die Leistung von Indexverarbeitungsvorgängen ist hauptsächlich davon abhängig, wo der Index im Speicher vorhanden ist, und welche Art von Renderinggerät verwendet wird. Anwendungen steuern die Speicherreservierung für Indexpuffer, wenn sie erstellt werden. Durch Festlegen des Arbeitsspeicherflags „D3DPOOL_SYSTEMMEM“ wird der Indexpuffer im Systemarbeitsspeicher erstellt. Wird das Arbeitsspeicherflag „D3DPOOL_DEFAULT“ verwendet, bestimmt der Gerätetreiber, wo der Arbeitsspeicher für den Indexpuffer am besten zugewiesen wird (in diesem Fall wird der Arbeitsspeicher häufig als „treiberoptimierter Arbeitsspeicher“ bezeichnet). Beim treiberoptimierten Arbeitsspeicher kann es sich um lokalen Videospeicher, nicht-lokalen Videospeicher oder Systemarbeitsspeicher handeln.

Das Festlegen des Verhaltensflags „D3DUSAGE_SOFTWAREPROCESSING“ beim Aufrufen der IDirect3DDevice9::CreateIndexBuffer-Methode gibt an, dass der Indexpuffer zusammen mit Softwarevertexverarbeitung verwendet werden soll. Dieses Flag ist in der Vertexverarbeitung im gemischten Modus (D3DCREATE_MIXED_VERTEXPROCESSING) erforderlich, wenn die Softwarevertexverarbeitung verwendet wird.

Die Anwendung kann Indizes direkt in einen Indexpuffer schreiben, der im treiberoptimierten Arbeitsspeicher zugeordnet ist. Mit dieser Technik wird später ein redundanter Kopiervorgang verhindert. Diese Technik funktioniert nicht optimal, wenn Ihre Anwendung Daten aus dem Indexpuffer zurückliest, da vom Host ausgeführte Lesevorgänge auf den treiberoptimierten Arbeitsspeicher sehr langsam sein können. Wenn Ihre Anwendung also während der Verarbeitung unregelmäßig Daten in oder aus dem Puffer lesen oder schreiben muss, ist ein Indexpuffer im Systemspeicher die bessere Wahl.

Hinweis

Verwenden Sie immer „D3DPOOL_DEFAULT“, es sei denn, Sie möchten keinen Videospeicher oder große Mengen an RAM mit gesperrten Seiten verwenden, wenn der Treiber Vertex- oder Indexpuffer im AGP-Arbeitsspeicher ablegt.

 

Erstellen eines Indexpuffers

Erstellen Sie ein Indexpufferobjekt, indem Sie die IDirect3DDevice9::CreateIndexBuffer-Methode aufrufen, bei der sechs Parameter zulässig sind.

  • Der erste Parameter gibt die Länge des Indexpuffers in Bytes an.

  • Der zweite Parameter besteht aus Steuerelementen für die Verwendung. Unter anderem bestimmt sein Wert, ob die Vertices, auf die die Indizes verweisen, Informationen zum Ausschneiden enthalten können. Um die Leistung zu verbessern, geben Sie „D3DUSAGE_DONOTCLIP“ an, wenn kein Ausschneiden erforderlich ist.

    Das Flag „D3DUSAGE_SOFTWAREPROCESSING“ kann festgelegt werden, wenn die Verarbeitung im gemischten Modus oder die Softwarevertexverarbeitung (D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING) für dieses Gerät aktiviert ist. „D3DUSAGE_SOFTWAREPROCESSING“ muss für Puffer festgelegt werden, die zusammen mit der Softwarevertexverarbeitung im gemischten Modus verwendet werden sollen. Das Flag darf jedoch nicht für die bestmögliche Leistung festgelegt werden, wenn Sie die Hardwareindexverarbeitung im gemischten Modus (D3DCREATE_HARDWARE_VERTEXPROCESSING) verwenden. Das Festlegen von „D3DUSAGE_SOFTWAREPROCESSING“ ist jedoch die einzige Option, wenn ein einzelner Puffer sowohl bei der Hardware- als auch bei der Softwarevertexverarbeitung verwendet wird. „D3DUSAGE_SOFTWAREPROCESSING“ ist für gemischte Geräte und Softwaregeräte zulässig.

    Es ist möglich, die Speicherung von Vertex- und Indexpuffern durch Angabe von „D3DPOOL_SYSTEMMEM“ im Systemarbeitsspeicher zu erzwingen, auch wenn die Indexverarbeitung auf der Hardware erfolgt. Dies stellt eine Möglichkeit dar, übermäßige Mengen von Arbeitsspeicher mit gesperrten Seiten zu vermeiden, wenn ein Treiber diese Puffer im AGP-Arbeitsspeicher ablegt.

  • Der dritte Parameter ist entweder der Member „D3DFMT_INDEX16“ oder „D3DFMT_INDEX32“ des Aufzählungstyps D3DFORMAT, der die Größe der einzelnen Indizes bestimmt.

  • Der vierte Parameter ist ein Member des Aufzählungstyps D3DPOOL, der das System anweist, wo im Arbeitsspeicher der neue Indexpuffer platziert werden soll.

  • Der letzte Parameter, den IDirect3DDevice9::CreateIndexBuffer akzeptiert, ist die Adresse einer Variablen, die bei einem erfolgreichen Aufruf mit einem Zeiger auf die neue IDirect3DIndexBuffer9-Schnittstelle des Vertexpufferobjekts versehen wird.

Das folgende C++-Codebeispiel zeigt, wie das Erstellen eines Indexpuffers im Code aussehen kann.

/*
 * 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;

Zugriff auf einen Indexpuffer

Indexpufferobjekte ermöglichen Anwendungen den direkten Zugriff auf den für Indexdaten zugewiesenen Arbeitsspeicher. Sie können einen Zeiger auf den Indexpuffer-Arbeitsspeicher abrufen, indem Sie die IDirect3DIndexBuffer9::Lock-Methode aufrufen und dann nach Bedarf auf den Speicher zugreifen, um den Puffer mit neuen Indexdaten zu füllen oder alle darin enthaltenen Daten zu lesen. Bei der Lock-Methode sind vier Parameter zulässig. Der erste Parameter OffsetToLock ist der Offset in den Indexdaten. Der zweite Parameter ist die Dateigröße der Indexdaten in Bytes. Der dritte Parameter ppbData, der bei der IDirect3DIndexBuffer9::Lock-Methode zulässig ist, ist die Adresse eines Bytezeigers, der bei einem erfolgreichen Aufruf mit einem Zeiger auf die Indexdaten versehen wird.

Der letzte Parameter, Flags, teilt dem System mit, wie der Arbeitsspeicher gesperrt werden soll. Sie können ihn verwenden, um anzugeben, wie die Anwendung auf die Daten im Puffer zugreift. Geben Sie Konstanten für den Parameter Flags entsprechend der Art und Weise an, auf die von Ihrer Anwendung auf die Indexdaten zugegriffen wird. Auf diese Weise kann der Treiber den Arbeitsspeicher sperren und die beste Leistung im Hinblick auf den angeforderten Zugriffstyp ermöglichen. Verwenden Sie das Flag „D3DLOCK_READONLY“, wenn Ihre Anwendung nur aus dem Indexpuffer-Arbeitsspeicher liest. Mit diesem Flag kann Direct3D seine internen Verfahren optimieren, um die Effizienz zu verbessern, da der Zugriff auf den Arbeitsspeicher schreibgeschützt ist.

Rufen Sie nach dem Ausfüllen oder Lesen der Indexdaten die IDirect3DIndexBuffer9::Unlock-Methode wie im folgenden Codebeispiel gezeigt auf:

// 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();

Hinweis

Wenn Sie einen Indexpuffer mit dem Flag „D3DUSAGE_WRITEONLY“ erstellen, verwenden Sie nicht das Flag „D3DLOCK_READONLY“ zum Sperren. Verwenden Sie das Flag „D3DLOCK_READONLY“, wenn Ihre Anwendung nur aus dem Indexpuffer-Arbeitsspeicher liest. Mit diesem Flag kann Direct3D seine internen Verfahren optimieren, um die Effizienz zu verbessern, da der Zugriff auf den Arbeitsspeicher schreibgeschützt ist.

Informationen zur Verwendung von „D3DLOCK_DISCARD“ oder „D3DLOCK_NOOVERWRITE“ für den Parameter Flags der IDirect3DIndexBuffer9::Lock-Methode finden Sie unter Leistungsoptimierungen (Direct3D 9).

 

Da Sie in C++ direkt auf den für den Indexpuffer zugewiesenen Arbeitsspeicher zugreifen, muss die Anwendung ordnungsgemäß auf den zugewiesenen Arbeitsspeicher zugreifen können. Andernfalls kann der Arbeitsspeicher ungültig werden. Verwenden Sie die Schrittweite des Indexformats, das von Ihrer Anwendung verwendet wird, um von einem Index im zugewiesenen Puffer zu einem anderen zu wechseln.

Rufen Sie Informationen zu einem Indexpuffer ab, indem Sie die IDirect3DIndexBuffer9::GetDesc-Methode aufrufen. Diese Methode füllt die Member der D3DINDEXBUFFER_DESC-Struktur mit Informationen zum Indexpuffer.

Direct3D-Ressourcen

Rendern aus Vertex- und Indexpuffern (Direct3D 9)

Vertexpuffer (Direct3D 9)