Zuordnen virtueller Adressen zu einem Speichersegment
Der Display-Miniporttreiber kann für jeden definierten Speicher- oder Blendenraumsegment angeben, ob virtuelle CPU-Adressen einer Zuordnung im Segment direkt zugeordnet werden können, indem er das Bitfeldflag CpuVisible im Flags-Element der DXGK_SEGMENTDESCRIPTOR-Struktur für das Segment festlegt.
Zum Zuordnen einer virtuellen CPU-Adresse zu einem Segment sollte das Segment über einen linearen Zugriff über die PCI-Blende verfügen. Anders ausgedrückt: Der Offset einer beliebigen Zuordnung innerhalb des Segments sollte mit dem Offset in der PCI-Blende identisch sein. Daher kann der Videospeicher-Manager die bus relative physische Adresse einer beliebigen Zuordnung basierend auf dem Offset der Zuordnung innerhalb des angegebenen Segments berechnen.
Das folgende Diagramm veranschaulicht, wie virtuelle Adressen einem linearen Speicherbereichssegment zugeordnet werden.
Das folgende Diagramm veranschaulicht, wie virtuelle Adressen den zugrunde liegenden Seiten eines linearen Öffnungsraumsegments zugeordnet werden.
Vor dem Zuordnen einer virtuellen Adresse zu einem Teil des Segments ruft der Videospeicher-Manager die DxgkDdiAcquireSwizzlingRange-Funktion des Anzeigeminiporttreibers auf, damit der Treiber die Blende einrichten kann, die für den Zugriff auf Bits der Zuordnung verwendet wird, die möglicherweise geschwenkt werden. Der Treiber kann weder den Offset in die PCI-Blende ändern, auf die auf die Zuordnung zugegriffen wird, noch den Raum, den die Zuordnung in der Blende beansprucht. Wenn der Treiber die Zuordnungs-CPU aufgrund dieser Einschränkungen nicht zugänglich machen kann (z. B. dass der Hardware möglicherweise die Blende ausging), räumt der Videospeicher-Manager die Zuordnung zum Systemspeicher aus und ermöglicht der Anwendung den Zugriff auf die bits dort.
Wenn sich der Inhalt einer zuvor erstellten Zuordnung im Systemspeicher befindet, wenn der Benutzermodusanzeigetreiber die pfnLockCb-Funktion aufruft, um direkten Zugriff auf den Speicher anzufordern, gibt der Videospeicher-Manager den Systemspeicherpuffer an den Anzeigetreiber für den Benutzermodus zurück, und der Anzeigeminiporttreiber ist nicht am Zugriff auf die Zuordnung beteiligt. Daher wird der Inhalt der Zuordnung nicht durch den Anzeigeminiporttreiber geändert und bleibt im ungesäuerten Format. Dies bedeutet, dass der Anzeigeminiporttreiber die Zuordnung aufheben muss, wenn eine CPU-fähige Zuordnung aus dem Videospeicher entfernt wird, damit die Anwendung direkt auf die resultierenden Systemspeicherbits zugreifen kann.
Wenn die GPU-Ressourcen, die einer derzeit für den direkten Anwendungszugriff zugeordneten Zuordnung zugeordnet sind, entfernt werden, wird der Inhalt der Zuordnung in den Systemspeicher übertragen, sodass die Anwendung weiterhin unter derselben virtuellen Adresse, aber einem anderen physischen Medium auf den Inhalt zugreifen kann. Um die Übertragung einzurichten, ruft der Videospeicher-Manager die DxgkDdiBuildPagingBuffer-Funktion des Anzeigeminiporttreibers auf, um einen Pagingpuffer zu erstellen, und der GPU-Planer ruft die DxgkDdiSubmitCommand-Funktion des Treibers auf, um den Pagingpuffer an die GPU-Ausführungseinheit in die Warteschlange zu stellen. Der hardwarespezifische Übertragungsbefehl befindet sich im Pagingpuffer. Weitere Informationen finden Sie unter Übermitteln eines Befehlspuffers. Der Videospeicher-Manager stellt sicher, dass der Übergang von Video zum Systemspeicher für die Anwendung nicht sichtbar ist. Der Treiber muss jedoch sicherstellen, dass die Bytereihenfolge einer Zuordnung über die PCI-Blende genau mit der Bytereihenfolge der Zuordnung übereinstimmt, wenn die Zuordnung entfernt wird.
Bei Blendenraumsegmenten befinden sich die zugrunde liegenden Bits der Zuordnung bereits im Systemspeicher, sodass keine Übertragung (Unwizzling) von Daten während des Entfernungsprozesses erforderlich ist. Daher kann eine CPU-zugängliche Zuordnung, die sich in einem Aperture-Space-Segment befindet, nicht geschwommen werden, wenn eine Anwendung direkt auf sie zugreift.
Wenn eine Oberfläche direkt über die CPU von einer Anwendung zugänglich ist, aber in einem Blendenraumsegment geschwommen wird, sollten die Anzeigetreiber die Oberfläche als zwei unterschiedliche Zuordnungen implementieren. Wenn der Benutzermodusanzeigetreiber eine solche Oberfläche erstellt, kann er die pfnAllocateCb-Funktion aufrufen und das NumAllocations-Element der D3DDDICB_ALLOCATE-Struktur auf 2 und die pPrivateDriverData-Member der D3DDDI_ALLOCATIONINFO Strukturen im pAllocationInfo-Array von D3DDDICB_ALLOCATE festlegen, um auf private Daten über die Zuordnungen (z. B. ihre geschwenkten und nicht verworrenen Formate) zu verweisen. Die Zuordnung, die von der GPU verwendet wird, enthält Bits im geschwungenen Format, und die Zuordnung, auf die die Anwendung zugreift, enthält die Bits im unwizzled-Format. Der Videospeicher-Manager ruft die DxgkDdiCreateAllocation-Funktion des Anzeigeminiporttreibers auf, um die Zuordnungen zu erstellen. Der Anzeigeminiporttreiber interpretiert die privaten Daten (im pPrivateDriverData-Member der DXGK_ALLOCATIONINFO-Struktur für jede Zuordnung), die vom Benutzermodusanzeigetreiber übergeben werden. Der Videospeicher-Manager kennt das Format der Zuordnungen nicht. Es ordnet nur Speicherblöcke bestimmter Größen und Ausrichtungen für die Zuordnungen zu. Ein Aufruf der Lock-Funktion des Benutzermodusanzeigetreibers zum Sperren der Oberfläche für die Verarbeitung führt zu den folgenden Aktionen:
Der Benutzermodusanzeigetreiber ruft die PfnRenderCb-Funktion auf, um den Unwizzle-Vorgang im Befehlspuffer an die Direct3D-Runtime und an den Anzeigeminiporttreiber zu übermitteln.
Der Benutzermodusanzeigetreiber ruft die pfnLockCb-Funktion auf, um die nicht zugeordnete Zuordnung zu sperren. Beachten Sie, dass der Benutzermodusanzeigetreiber das D3DDDILOCKCB_DONOTWAIT-Flag im Flags-Member der D3DDDICB_LOCK-Struktur nicht festlegen darf.
Die pfnLockCb-Funktion wartet, bis die Übertragung (Aufheben) zwischen Zuordnungen ausgeführt wird.
Die pfnLockCb-Funktion fordert an, dass der Anzeigeminiporttreiber eine virtuelle Adresse für die nicht zugeordnete Zuordnung erhält und die virtuelle Adresse an den Benutzermodusanzeigetreiber im pData-Member von D3DDDICB_LOCK zurückgibt.
Der Benutzermodusanzeigetreiber gibt die virtuelle Adresse der nicht zugeordneten Zuordnung an die Anwendung im pSurfData-Member von D3DDDIARG_LOCK zurück.