Befehls- und Vertexpufferzuordnung

In Direct3D werden drei Puffertypen verwendet:

  • Implizite Vertexpuffer, die nur für die interne Verwendung erstellt werden; Das heißt, Anwendungen sind ihnen nicht bekannt. Nach der Kontexterstellung wird immer ein impliziter Vertexpuffer erstellt, in dem Direct3D Vertexdaten speichert.

  • Explizite Vertexpuffer, die nur als Reaktion auf eine Anwendungsanforderung erstellt werden. Direct3D speichert dann Scheitelpunktdaten in expliziten Vertexpuffern.

  • Befehlspuffer, die nur für die interne Verwendung erstellt werden; Das heißt, Anwendungen kennen Befehlspuffer nicht. Direct3D speichert Befehlsdaten in Befehlspuffern.

Implizite Vertexpuffer sind spezielle Vertexpuffer, die intern von Direct3D für die Batchverarbeitung verwendet werden. Sie werden während der Geräteinitialisierung erstellt und können multibuffert sein. Sie sind immer lese-/schreibbar, sodass sie nicht in den Videospeicher (für Microsoft DirectX 6.0 und höhere Versionen) eingefügt werden sollten. Dieser Puffertyp ist durch das Fehlen der flags DDSCAPS2_VERTEXBUFFER und DDSCAPS2_COMMANDBUFFER gekennzeichnet.

Explizite Vertexpuffer werden von der Anwendung erstellt und gesteuert. Diese können nicht multibuffert und nicht in den lokalen oder nicht lokalen Videospeicher eingefügt werden, es sei denn, das flag DDSCAPS_WRITEONLY ist festgelegt. Explizite Vertexpuffer werden mit DDSCAPS_VERTEXBUFFER gekennzeichnet.

Befehlspuffer werden von Direct3D zum Batchen von Befehlen verwendet. Sie können multibuffert sein und werden für alle APIs mit Ausnahme von TLVERTEX- oder unclipped execute-buffer-API-Aufrufen verwendet. Dieser Puffertyp wird durch das Flag DDSCAPS2_COMMANDBUFFER gekennzeichnet. Sie sind immer schreibgeschützt, obwohl kein explizites Flag festgelegt ist und sie nie ungültige Anweisungen enthalten.

Standardmäßig weist die Direct3D-Runtime alle diese Puffer zu. Der Zugriff auf implizite Vertexpuffer und Befehlspuffer erfolgt über die Oberflächen, denen sie zugeordnet sind. Alle Puffer werden an den D3dDrawPrimitives2-Rückruf des Treibers übergeben.

Vom Treiber zugewiesene Scheitelpunkt- und Befehlspuffer

Ein Direct3D-Treiber führt optional die Zuordnung von Vertex- und Befehlspuffern durch Bereitstellen von Rückruffunktionen aus. Um diese Rückruffunktionen bereitstellen zu können, füllt der Direct3D-Treiber eine DD_D3DBUFCALLBACKS-Struktur aus und verweist den lpD3DBufCallbacks-Member der DD_HALINFO-Struktur darauf. DD_HALINFO wird von DrvGetDirectDrawInfo als Reaktion auf die Initialisierung der DirectDraw-Komponente des Treibers zurückgegeben. Die in der DD_D3DBUFCALLBACKS-Struktur gemeldeten Rückrufe sind:

Diese Funktionen werden auf die gleiche Weise wie die DdXxxSurface-Rückrufe (z. B. DdCanCreateSurface) und nur aufgerufen, wenn das flag DDSCAPS_EXECUTEBUFFER festgelegt ist. Die Flags für die Puffererstellung sind DDSCAPS_WRITEONLY, DDSCAPS2_VERTEXBUFFER und DDSCAPS2_COMMANDBUFFER.

Treiber bestimmen den Typ des angeforderten Puffers, indem sie den ddsCaps-Member der DD_SURFACE_LOCAL Struktur überprüfen, die an den Rückruf CanCreateExecuteBuffer und CreateExecuteBuffer übergeben wird, auf die folgenden Flags:

  • DDSCAPS_VERTEXBUFFER gibt an, dass der Treiber einen expliziten Vertexpuffer zuordnen soll.

  • DDSCAPS_COMMANDBUFFER gibt an, dass der Treiber einen Befehlspuffer zuordnen soll.

  • Wenn keines der Flags festgelegt ist, sollte der Treiber einen impliziten Vertexpuffer zuordnen.

Der Treiber ordnet Vertex- und Befehlspuffer intern zu und durchläuft diese Puffer. Direct3D füllt ein bestimmtes Paar aus, während die Hardware asynchron aus den anderen Puffern in der Warteschlange gerendert wird. Dies ist beim direkten Speicherzugriff (Direct Memory Access, DMA) sehr nützlich.

Puffer in einem Multibuffering-Satz können sich in verschiedenen Speichertypen befinden, d. h. im System- oder Videospeicher. Wenn der Treiber aufgerufen wird, um den ersten Puffer zu erstellen, erstellt er den Satz sofort und gibt den ersten Puffer in der Gruppe auf Direct3D zurück. Der Treiber verwendet Flags, um den Typ des Arbeitsspeichers anzugeben, den er zum Zuordnen der einzelnen Puffer in der Gruppe verwendet hat. Der Treiber sollte für jeden Aufruf von D3dDrawPrimitives2 einen neuen Puffer im Systemspeicher zurückgeben, wenn das flag D3DHALDP2_SWAPVERTEXBUFFER oder D3DHALDP2_SWAPCOMMANDBUFFER festgelegt ist. Wenn sich der zurückgegebene Puffer im Videospeicher befindet, sollte das entsprechende D3DHALDP2_VIDMEMVERTEXBUF- oder D3DHALDP2_VIDMEMCOMMANDBUF-Flag festgelegt werden.

Gelegentlich fordert Direct3D die Mindestgröße für den nächsten Puffer an. Wenn die Größe zu groß ist, sollte der Treiber den Puffer im Systemspeicher (eine Hintergrundoberfläche) zuordnen. Wenn die Größe zu klein ist, darf der Treiber einen größeren Puffer bereitstellen. Der Treiber sollte nachverfolgen, wie viele Puffer und welche Speichertypen sie sind, und beim Beenden alles sauber.