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.
Direct3D Version 9 Hinweis:

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.

Hinweis Die DxgkDdiCreateAllocation-Funktion des Anzeigeminiporttreibers wird nicht aufgerufen, wenn eine neue instance einer Zuordnung erstellt wird. Instanzen werden für den Anzeigeminiporttreiber als Zuordnungen angezeigt, die gleichzeitig an mehreren verschiedenen Speicherorten ausgelagert werden.
 
Der Videospeicher-Manager schlägt möglicherweise eine Sperre fehl, in der das Flag Bitfeld verwerfen festgelegt ist, da der Videospeicher-Manager keine neue instance erstellen oder eine vorhandene instance einer Zuordnung wiederverwenden kann. Wenn dieser Fehler auftritt, sollte der Anzeigetreiber im Benutzermodus die PfnRenderCb-Funktion aufrufen, um den aktuellen Befehlspuffer in den Kernel zu leeren. Durch diese Leerung des Befehlspuffers werden möglicherweise einige Instanzen der Zuordnung außer Kraft gesetzt, die nicht mit dem Flag Bitfeld verwerfen gesperrt werden konnten.

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
Durch festlegen des Flags "Bitfeld verwerfen " ermittelt der Speicher-Manager, ob er die Zuordnung umbenennen soll oder den Anwendungsthread so lange anhalten soll, bis sich die Zuordnung im Leerlauf befindet. Weitere Informationen zum Umbenennen einer Zuordnung finden Sie unter Anfordern einer Umbenennung einer Zuordnung. Der Treiber kann eine eigene Umbenennungsunterstützung oder die Unterstützung für die Umbenennung des Speicher-Managers verwenden. Um seine eigene Umbenennungsunterstützung zu verwenden, legt der Treiber das DonotWait-Bitfeldflag als Reaktion auf einen Lock-Aufruf mit dem Set "Bitfeldflag verwerfen" oder als Reaktion auf einen ResourceMap-Aufruf mit dem D3D10_DDI_MAP_WRITE_DISCARD-Wert fest. Das Festlegen des DonotWait-Bitfeldflags führt dazu, dass der Speicher-Manager den Aufruf von pfnLockCb mit D3DERR_WASSTILLDRAWING fehlschlägt, wenn die Grafikhardware weiterhin die Zuordnung verwendet. Ein solcher Fehler weist darauf hin, dass der Benutzermodusanzeigetreiber die Zuordnung umbenennen oder mehrfach puffert.
Hinweis Das DonotWait-Bitfeldflag hat keine Auswirkungen auf den Speicher-Manager, wenn auch das Flag "Bitfeld verwerfen" festgelegt ist.
 
Der Benutzermodusanzeigetreiber sollte das IgnoreSync-Bitfeldflag im Flags-Element von D3DDDICB_LOCK festlegen, wenn der Speicher-Manager nicht benötigt, um zu überprüfen, ob die Grafikhardware die Zuordnung verwendet. Der Benutzermodusanzeigetreiber muss dann den Zugriff auf die Zuordnung ordnungsgemäß synchronisieren. Wenn das DonotWait-Bitfeldflag nicht mit dem IgnoreSync-Bitfeldflag angegeben wird, ignoriert der Speicher-Manager das IgnoreSync-Bitfeldflag.
Hinweis Das IgnoreSync-Bitfeldflag hat keine Auswirkungen auf den Speicher-Manager, wenn auch das Flag "Bitfeld verwerfen" festgelegt ist.
 
Beispiel

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)

Weitere Informationen

D3D10DDIARG_CREATERESOURCE

D3D11DDIARG_CREATERESOURCE

D3DDDIARG_LOCK

D3DDDICB_LOCK

D3DDDI_DEVICECALLBACKS

Sperre

ResourceMap

ResourceUnmap