PFND3DDDI_LOCKCB Rückruffunktion (d3dumddi.h)
Die pfnLockCb-Funktion sperrt eine Zuordnung und ruft einen Zeiger auf die Zuordnung vom Display-Miniporttreiber oder Videospeicher-Manager ab.
Syntax
PFND3DDDI_LOCKCB Pfnd3dddiLockcb;
HRESULT Pfnd3dddiLockcb(
HANDLE hDevice,
D3DDDICB_LOCK *unnamedParam2
)
{...}
Parameter
hDevice
Ein Handle für das Anzeigegerät (Grafikkontext).
unnamedParam2
pData [in, out]
Ein Zeiger auf eine D3DDDICB_LOCK-Struktur , die die Zuordnung zu sperren beschreibt.
Rückgabewert
pfnLockCb gibt einen der folgenden Werte zurück:
Rückgabecode | Beschreibung |
---|---|
S_OK | Die Zuordnung wurde erfolgreich gesperrt. |
D3DERR_NOTAVAILABLE | Eine Öffnung war nicht verfügbar. |
D3DERR_WASSTILLDRAWING | Die Zuordnung wurde noch zum Rendern verwendet. |
D3DDDIERR_CANTEVICTPINNEDALLOCATION | Die Zuordnung konnte aufgrund der Nichtverfügbarkeit einer Entwizzling-Öffnung und der Unfähigkeit, die Zuordnung zu entfernen, nicht gesperrt werden, da sie angeheftet wurde. |
E_OUTOFMEMORY | pfnLockCb konnte aufgrund unzureichenden Arbeitsspeichers nicht abgeschlossen werden (diese Situation tritt auf, wenn sich das System in einer extrem geringen Speichersituation befindet und nicht genügend Speicherplatz zum Zuordnen des Arrays von Seiten vorhanden ist). |
E_INVALIDARG | Die Parameter wurden überprüft und als falsch ermittelt. |
D3DDDIERR_DEVICEREMOVED | pfnLockCb konnte nicht bewirken, dass der Videospeicher-Manager und der Anzeige-Miniporttreiber die entsprechenden Aktionen ausführt, da ein Plug & Play (PnP) oder ein TimeoutErkennungs- und Wiederherstellungsereignis (Timeout Detection and Recovery, TDR) aufgetreten ist. Die Anzeigetreiberfunktion für den Benutzermodus, die pfnLockCb (in der Regel die Lock - oder ResourceMap-Funktion ) aufgerufen hat, muss diesen Fehlercode an die Direct3D-Runtime zurückgeben. Direct3D Version 9 Hinweis: Weitere Informationen zum Zurückgeben von Fehlercodes finden Sie unter Zurückgeben von Fehlercodes, die von Laufzeitfunktionen empfangen wurden. Direct3D-Versionen 10 und 11 Hinweis: Wenn die Treiberfunktion keinen Wert zurückgibt (d. h. void für einen Rückgabeparametertyp hat), ruft die Treiberfunktion die PfnSetErrorCb-Funktion auf, um einen Fehlercode zurück an die Runtime zu senden. Weitere Informationen zur Behandlung von Fehlercodes finden Sie unter Behandeln von Fehlern. |
Diese Funktion gibt möglicherweise auch andere HRESULT-Werte zurück.
Hinweise
Der Anzeigetreiber für den Benutzermodus kann die PfnLockCb-Funktion der Microsoft Direct3D-Runtime aufrufen, um eine Zuordnung zu sperren und einen Zeiger auf die Zuordnung vom Display-Miniporttreiber oder Videospeicher-Manager abzurufen. Der Benutzermodusanzeigetreiber ruft in der Regel pfnLockCb als Reaktion auf einen Aufruf seiner Lock - oder ResourceMap-Funktion (oder anderer Variationen von ResourceMap wie DynamicIABufferMapDiscard) auf, um eine Ressource oder eine Oberfläche innerhalb der Ressource zu sperren. Vor der Rückkehr vom Lock - oder ResourceMap-Aufruf muss der Anzeigetreiber im Benutzermodus zuerst die Ressource oder Oberfläche der entsprechenden Zuordnung zuordnen und dann pfnLockCb aufrufen, um die Zuordnung zu sperren. Die Zuordnung muss gesperrt werden, bevor sie aus gelesen oder in geschrieben werden kann, da sperren:
- Garantiert, dass der virtuelle Adressbereich für die Zuordnung für die Dauer der Sperre unverändert, gültig, lesbar und beschreibbar bleibt. Der Videospeicher-Manager bietet diese Garantie.
- Bietet eine Möglichkeit zum Synchronisieren der Lese- und Schreibvorgänge der Zuordnung mit Grafikhardwarezugriffen der Zuordnung. Der Videospeicher-Manager und der Display-Miniporttreiber führen die Synchronisierung durch.
Der Anzeigetreiber für den Benutzermodus ruft in der Regel die Funktionen pfnLockCb und pfnUnlockCb auf, die jedem Aufruf seiner Lock - bzw . Unlock-Funktionen entsprechen, außer wenn der Treiber Ressourcen verarbeitet, in denen das Dynamische Bitfeldflag im Flags-Element der D3DDDIARG_CREATERESOURCE-Struktur festgelegt wurde, als die Ressourcen erstellt wurden. Die Laufzeit fordert häufig an, dass der Treiber diese Ressourcentypen sperrt, häufig mit dem NoOverwrite-Bitfeldflag , das im Flags-Member der D3DDDIARG_LOCK-Struktur festgelegt ist. Da Daten in solchen Ressourcen nicht geändert werden sollen (wie durch NoOverwrite angegeben), beansprucht der Aufruf von pfnLockCb für jede Sperranforderung eine übermäßige Verarbeitungszeit. Um zu verhindern, dass pfnLockCb für jede Sperranforderung aufgerufen wird, kann der Treiber den virtuellen Speicherzeiger zwischenspeichern, den er im pSurfData-Element von D3DDDIARG_LOCK zurückgibt, wenn seine Lock-Funktion mit dem NoOverwrite-Bitfeldflag aufgerufen wird. Der Treiber kann pfnLockCb jedoch weiterhin aufrufen, wenn seine Lock-Funktion aufgerufen wird, wobei entweder das Flag Bitfeld verwerfen oder keine Flags festgelegt sind.
Direct3D-Versionen 10 und 11 Hinweis:
Der Anzeigetreiber für den Benutzermodus ruft in der Regel die Funktionen pfnLockCb und pfnUnlockCb auf, die jedem Aufruf der Funktionen ResourceMap und ResourceUnmap (oder andere Variationen dieser Funktionen) entsprechen. Dies geschieht nicht, wenn der Treiber Ressourcen verarbeitet, in denen der wert D3D10_DDI_USAGE_DYNAMIC beim Erstellen der Ressourcen im Verwendungselement der D3D10DDIARG_CREATERESOURCE - oder D3D11DDIARG_CREATERESOURCE-Struktur festgelegt wurde. Die Laufzeit fordert häufig an, dass der Treiber diese Ressourcentypen sperrt, häufig durch Übergabe des werts D3D10_DDI_MAP_WRITE_NOOVERWRITE an den DDIMap-Parameter im Aufruf von ResourceMap. Da Daten in solchen Ressourcen nicht geändert werden sollen (wie durch D3D10_DDI_MAP_WRITE_NOOVERWRITE angegeben), beansprucht der Aufruf von pfnLockCb für jede Sperranforderung eine übermäßige Verarbeitungszeit. Um den Aufruf von pfnLockCb für jede Sperranforderung zu verhindern, kann der Treiber den virtuellen Speicherzeiger zwischenspeichern, den er im pMappedSubResource-Parameter zurückgibt, wenn seine ResourceMap-Funktion mit D3D10_DDI_MAP_WRITE_NOOVERWRITE aufgerufen wird. Der Treiber kann pfnLockCb jedoch weiterhin aufrufen, wenn seine ResourceMap-Funktion mit dem D3D10_DDI_MAP_WRITE_DISCARD-Wert oder 0 aufgerufen wird, der an den DDIMap-Parameter übergeben wird.
Die Anwendung verfügt zwar nicht über eine ausstehende Sperre für die Ressource, die dem Zeiger des virtuellen Speichers zugeordnet ist, aber der Treiber hebt die Zwischenspeicherung des virtuellen Speicherzeigers in der Regel auf, indem er die PfnUnlockCb-Funktion aufruft , bevor der Treiber die PfnRenderCb-Funktion aufruft . Wenn die Sperre nicht zwischengespeichert ist oder die Sperre nicht aufgehoben werden kann, weil die Ressource in der Anwendung noch gesperrt ist, kann die Hardware aus einer gesperrten Zuordnung gerendert werden. Der Videospeicher-Manager kann diese Betriebsart nicht unterstützen, wenn sich die Zuordnung im lokalen Videospeicher befindet. Daher entfernt der Speicher-Manager die Zuordnung zum System- oder AGP-Speicher, wenn der Speicher-Manager diese Situation erkennt. Wenn die Zuordnung im System- oder AGP-Speichersegment nicht unterstützt wird, schlägt der Speicher-Manager den Aufruf von pfnRenderCb mit D3DDDIERR_CANTRENDERLOCKEDALLOCATION fehl. Daher sollten Vertex- und Indexpufferzuordnungen, die als Reaktion auf die Erstellung von Ressourcen zugeordnet werden, in denen das Flag dynamische Bitfeld im Flags-Member von D3DDDIARG_CREATERESOURCE festgelegt wird (oder der D3D10_DDI_USAGE_DYNAMIC Wert im Member Usage von D3D10DDIARG_CREATERESOURCE oder D3D11DDIARG_CREATERESOURCE festgelegt wird), in System- oder AGP-Segmenten unterstützt werden.
Das Festlegen des Flags Bitfeld verwerfen im Flags-Element von D3DDDICB_LOCK in einem Aufruf von pfnLockCb bewirkt, dass der Videospeicher-Manager eine neue instance der gesperrten Zuordnung erstellt. Der Videospeicher-Manager stellt die neue instance dar, indem ein neues Handle an den Benutzermodusanzeigetreiber im hAllocation-Element von D3DDDICB_LOCK zurückgegeben wird.
Nachdem der Befehlspuffer geleert wurde, muss der Anzeigetreiber im Benutzermodus versuchen, die Oberfläche mithilfe der Bitfeldflags Discard und NoExistingReference erneut zu sperren. Das NoExistingReference-Bitfeldflag gibt dem Videospeicher-Manager an, dass der Treiber derzeit keinen Verweis auf instance der Zuordnung hat, die in der Warteschlange des Befehlspuffers gesperrt ist. Der Videospeicher-Manager kann dann alle instance der Zuordnung wiederverwenden, um die Sperre zu behandeln, einschließlich der aktuellen instance.
Nach einem Aufruf von pfnLockCb , in dem das Flag Bitfeld verwerfen festgelegt ist, sollte der Benutzermodusanzeigetreiber immer nach einem aktualisierten Handle-Wert im hAllocation-Member von D3DDDICB_LOCK suchen. Wenn ein neues Zuordnungshandle bereitgestellt wird, sollte der Anzeigetreiber für den Benutzermodus seine interne Datenstruktur aktualisieren, um auf das neue Zuordnungshandle zu verweisen. Der Anzeigetreiber für den Benutzermodus sollte dem aktuellen Befehlspuffer auch eine neu programmierte Version der gesperrten Zuordnungsbasisadresse hinzufügen (da Zuordnungsinstanzen unterschiedliche Basisadressen enthalten). Der Videospeicher-Manager überprüft die Verwendung von Zuordnungsinstanzen, die vom Treiber verwendet werden, und lehnt DMA-Puffer ab, die die Zuordnungsinstanzen falsch verwenden (d. a. Aufrufe von pfnPresentCb und pfnRenderCb schlagen fehl, wenn sie Zuordnungsinstanzen fälschlicherweise verwenden). Nachdem der Treiber auf eine bestimmte instance einer Zuordnung verweist, kann der Fahrer nicht mehr auf eine vorherige instance derselben Zuordnung verweisen. Wenn beispielsweise ein Befehlspuffer die Zuordnung A verwendet und derzeit die Instanzen A0 und A1 verwendet, wird A0 ungültig, sobald A1 verwendet wird (d. h. in der Patchspeicherortliste angezeigt wird). Der Anzeige-Miniporttreiber kann eine Patchspeicherortliste generieren, die sowohl auf A0 als auch auf A1 verweist. Die Verweise müssen jedoch sortiert werden (d. a. A0 kann zuerst verwendet werden; A0 wird ungültig, sobald A2 verwendet wird; A1 wird ungültig, wenn A2 verwendet wird usw.
Der Anzeigetreiber für den Benutzermodus kann pfnLockCb für Systemspeicherbelegungen aufrufen, auch wenn der Arbeitsspeicher nicht vorab zugewiesen wurde, da der Anzeige-Miniporttreiber diese Zuordnungen möglicherweise über DMA sendet oder asynchron an Grafikhardware überträgt. Bevor eine Anwendung auf die Oberfläche schreiben darf, müssen daher der Display-Miniporttreiber und der Videospeicher-Manager benachrichtigt werden, damit sie die Sperre bei Bedarf blockieren können.
Der Anzeigetreiber für den Benutzermodus kann auch Unterbereiche einer Zuordnung sperren. Diese Art von Sperre ist in der Regel nicht erforderlich, wenn eine entsperrende oder linearisierende Hardwareblende verfügbar ist, da in diesem Fall der Benutzermodus-Anzeigetreiber eine Sperre für die gesamte Zuordnung zum Unterbereich übersetzen kann, indem der Zeiger den Zeiger ausgleicht. Wenn pfnLockCb jedoch mit D3DERR_NOTAVAILABLE fehlschlägt, um anzugeben, dass keine Blende verfügbar ist, fordert der Speicher-Manager den Benutzermodusanzeigetreiber auf, den Inhalt des Videospeichers zu kopieren. Der Anzeigetreiber für den Benutzermodus entfernt oder linearisiert den Inhalt des Videospeichers, während er sie in einen anderen Speicherbereich kopiert. In diesem Fall kann der Benutzermodus-Anzeigetreiber eine Liste der zu kopierenden Seiten bereitstellen, um große Mengen an Kopiervorgängen zu sparen, wenn kleine Unterbereiche in einer großen Zuordnung gesperrt werden. Beachten Sie, dass der Speicher-Manager einen Aufruf von pfnLockCb mit D3DERR_NOTAVAILABLE fehlschlägt, wenn der Benutzermodusanzeigetreiber das LockEntire-Bitfeldflag nicht im Flags-Element der D3DDDICB_LOCK-Struktur festgelegt und keine Seitenliste im pPages-Element von D3DDDICB_LOCK angegeben hat. Wenn der Benutzermodusanzeigetreiber das LockEntire-Bitfeldflag festlegt, muss er auch die NumPages - und pPages-Member von D3DDDICB_LOCK auf 0 bzw. NULL festlegen. Der Anzeigetreiber für den Benutzermodus sollte immer eine Seitenliste in pPages bereitstellen, wenn eine Zuordnung gesperrt wird, die mit einem permanenten Sicherungsspeicher erstellt wurde. In diesem Fall verwendet der Speicher-Manager die Seitenliste, um nur bestimmte Seiten als modifiziert zu markieren, und es ist nicht erforderlich, die gesamte Zuordnung aus dem Sicherungsspeicher zu kopieren, wenn er zum Rendern verwendet wird.
Der Benutzermodusanzeigetreiber kann pfnLockCb aufrufen, um mehrere Swizzlingbereiche für eine einzelne Zuordnung abzurufen (z. B. einen Swizzlingbereich für jede MIP-Ebene). Wenn der Treiber keinen der Bereiche abrufen kann, entfernt die Direct3D-Runtime die gesamte Zuordnung, um die Sperre (alle MIP-Ebenen) zu behandeln, und gibt alle Swizzlingbereiche zurück.
Wenn der Benutzermodusanzeigetreiber anfordert, der Zuordnung einen Schwenkbereich zuzuweisen, fordert der Treiber effektiv Zugriff auf die ungewizzten Bits der Zuordnung an. Bei solchen Anforderungen stellt der Videospeicher-Manager entweder die Zuweisung in ein Speichersegment ein und richtet einen Swizzlingbereich ein, um auf die Zuordnung oder die Seiten in der Zuordnung in ein Speichersegment zuzugreifen, und entfernt dann die Zuordnung zum Systemspeicher, während er anfordert, dass der Treiber die Zuordnung auf dem Weg zum Systemspeicher aufheben muss. Eine Zuordnung, die nicht für den Systemspeicher freigegeben wurde, wird neu (durch Auslagerung in Den Videospeicher) geändert, bevor die GPU die Zuordnung erneut verwendet. Daher kann der Treiber keine Sperre vom Typ No-Overwrite anfordern (durch Festlegen des DonotWait-Bitfeldflags ), wenn er einen Schwenkbereich abruft. Ebenso kann der Treiber nicht auf eine Zuordnungssperre in einem DMA-Puffer verweisen, der an die GPU übermittelt wird (da der DMA-Puffer abgelehnt wird).
Der Anzeigetreiber für den Benutzermodus kann eine geschwenkte Zuordnung sperren, ohne einen Schwenkbereich abzurufen, wenn der Treiber auf die Bits der Zuordnung in einem geschwommenen Format zugreifen muss. In diesem Fall stellt der Videospeicher-Manager dem Treiber einen Zeiger auf die geschwommenen Bits der Zuordnung bereit. Der Treiber kann jedoch keinen Zeiger auf die geschwommenen Bits der Zuordnung anfordern, während eine Anforderung für die nicht verworfenen Bits aussteht und umgekehrt (d. h., eine Sperre ist derzeit für die Zuordnung mit einem erworbenen Swizzlingbereich ausstehend).
Der Benutzermodusanzeigetreiber sollte das Bitfeldflag Verwerfen im Flags-Element von D3DDDICB_LOCK im PfnLockCb-Aufruf in den folgenden Situationen übergeben:
- Wenn die Direct3D-Runtime das Bitfeldflag Verwerfen im Flags-Element der D3DDDIARG_LOCK-Struktur im Aufruf der Benutzermodusanzeigetreiber-Funktion "Sperren " übergibt
- Wenn die Runtime den D3D10_DDI_MAP_WRITE_DISCARD Wert an den DDIMap-Parameter im Aufruf der ResourceMap-Funktion des Treibers übergibt
Das folgende Codebeispiel zeigt, wie das Flag "Bitfeld verwerfen" in einem Aufruf von pfnLockCb verwendet wird.
HRESULT hr;
D3DDDICB_LOCK LockData;
LockData.hAllocation = AllocationToLock;
LockData.Flags.Discard = TRUE;
hr = pfnLockCb(&LockData)
if (FAILED(hr)) {
FlushAccumulatedCommandBufferToKernel();
LockData.Flags.Discard = TRUE;
LockData.Flags.NoExistingReference = TRUE;
hr = pfnLockCb(&LockData);
if (FAILED(hr)) {
// Fails the lock to the application
}
}
UpdateAllocationHandleInUMDDataStructure(LockData.hAllocation);
ProgramSurfaceBaseAddressInCurrentCommandBuffer(LockData.hAllocation);
Anforderungen
Anforderung | Wert |
---|---|
Unterstützte Mindestversion (Client) | Verfügbar in Windows Vista und höheren Versionen der Windows-Betriebssysteme. |
Zielplattform | Desktop |
Kopfzeile | d3dumddi.h (include D3dumddi.h) |