Mapping degli indirizzi virtuali a un segmento di memoria
Il driver miniport di visualizzazione può specificare, per ogni segmento di spazio memoria o spazio di apertura definito, se gli indirizzi virtuali della CPU possono essere mappati direttamente a un'allocazione situata nel segmento impostando il flag di campo di bit CpuVisible nel membro Flags della struttura DXGK_SEGMENTDESCRIPTOR per il segmento.
Per eseguire il mapping di un indirizzo virtuale della CPU a un segmento, il segmento deve avere accesso lineare tramite l'apertura PCI. In altre parole, l'offset di qualsiasi allocazione all'interno del segmento deve corrispondere all'offset nell'apertura PCI. Pertanto, il gestore della memoria video può calcolare l'indirizzo fisico relativo al bus di qualsiasi allocazione in base all'offset dell'allocazione all'interno del segmento specificato.
Il diagramma seguente illustra il mapping degli indirizzi virtuali a un segmento di spazio di memoria lineare.
Il diagramma seguente illustra il mapping degli indirizzi virtuali alle pagine sottostanti di un segmento di spazio di apertura lineare.
Prima di eseguire il mapping di un indirizzo virtuale a una parte del segmento, il gestore della memoria video chiama la funzione DxgkDdiAcquireSwizzlingRange del driver di visualizzazione in modo che il driver possa configurare l'apertura usata per accedere ai bit dell'allocazione che potrebbe essere swizzled. Il driver non può modificare né l'offset nell'apertura PCI in cui si accede all'allocazione né la quantità di spazio necessaria per l'allocazione nell'apertura. Se il driver non è in grado di rendere accessibile l'allocazione della CPU in base a questi vincoli (ad esempio, l'hardware potrebbe espellere l'apertura senza interruzioni), gestione memoria video rimuove l'allocazione alla memoria di sistema e consente all'applicazione di accedere ai bit in tale posizione.
Se il contenuto di un'allocazione creata in precedenza è in memoria di sistema quando il driver di visualizzazione in modalità utente chiama la funzione pfnLockCb per richiedere l'accesso diretto alla memoria, gestione memoria video restituisce il buffer di memoria di sistema al driver di visualizzazione in modalità utente e il driver miniport di visualizzazione non è coinvolto nell'accesso all'allocazione. Pertanto, il contenuto dell'allocazione non viene modificato dal driver miniport di visualizzazione e rimane in formato nonwizzled. Ciò implica che quando un'allocazione accessibile dalla CPU viene rimossa dalla memoria video, il driver miniport di visualizzazione deve rimuovere l'allocazione in modo che i bit di memoria di sistema risultanti possano essere accessibili direttamente dall'applicazione.
Se le risorse GPU associate a un'allocazione attualmente mappata per l'accesso diretto all'applicazione vengono rimosse, il contenuto dell'allocazione viene trasferito alla memoria di sistema in modo che l'applicazione possa continuare ad accedere al contenuto allo stesso indirizzo virtuale ma a un supporto fisico diverso. Per configurare il trasferimento, il gestore della memoria video chiama la funzione DxgkDdiBuildPagingBuffer del driver di miniport per creare un buffer di paging e l'utilità di pianificazione GPU chiama la funzione DxgkDdiSubmitCommand del driver per accodare il buffer di paging all'unità di esecuzione gpu. Il comando di trasferimento specifico dell'hardware si trova nel buffer di paging. Per altre informazioni, vedere Invio di un buffer dei comandi. La gestione memoria video garantisce che la transizione del video alla memoria di sistema sia invisibile all'applicazione. Tuttavia, il driver deve garantire che l'ordinamento dei byte di un'allocazione tramite l'apertura PCI corrisponda esattamente all'ordinamento dei byte dell'allocazione quando l'allocazione viene rimossa.
Per i segmenti dello spazio di apertura, i bit sottostanti dell'allocazione sono già presenti nella memoria di sistema, quindi non è necessario alcun trasferimento (unswizzling) di dati durante il processo di rimozione. Pertanto, un'allocazione accessibile dalla CPU situata in un segmento di spazio di apertura non può essere swizzled se è accessibile direttamente da un'applicazione.
Se una superficie sarà accessibile direttamente tramite la CPU da un'applicazione, ma sarà swizzled in un segmento di spazio di apertura, i driver di visualizzazione devono implementare la superficie come due allocazioni diverse. Quando il driver di visualizzazione in modalità utente crea una superficie di questo tipo, può chiamare la funzione pfnAllocateCb e può impostare il membro NumAllocations della struttura D3DDDICB_ALLOCATE su 2 e i membri pPrivateDriverData delle strutture D3DDDI_ALLOCATIONINFO nella matrice pAllocationInfo di D3DDDICB_ALLOCATE in modo da puntare a dati privati sulle allocazioni (ad esempio i relativi formati swizzled e nonwizzled). L'allocazione che verrà usata dalla GPU contiene bit in formato swizzled e l'allocazione a cui l'applicazione accederà contiene i bit in formato nonwizzled. Il gestore della memoria video chiama la funzione DxgkDdiCreateAllocation del driver miniport di visualizzazione per creare le allocazioni. Il driver miniport di visualizzazione interpreta i dati privati (nel membro pPrivateDriverData della struttura DXGK_ALLOCATIONINFO per ogni allocazione) passati dal driver di visualizzazione in modalità utente. Il gestore della memoria video non è a conoscenza del formato delle allocazioni; alloca solo blocchi di memoria di determinate dimensioni e allineamenti per le allocazioni. Una chiamata alla funzione Lock del driver di visualizzazione in modalità utente per bloccare la superficie per l'elaborazione causa le azioni seguenti:
Il driver di visualizzazione in modalità utente chiama la funzione pfnRenderCb per inviare l'operazione unswizzle nel buffer dei comandi al runtime Direct3D e al driver miniport di visualizzazione.
Il driver di visualizzazione in modalità utente chiama la funzione pfnLockCb per bloccare l'allocazione non guidata. Si noti che il driver di visualizzazione in modalità utente non deve impostare il flag D3DDDILOCKCB_DONOTWAIT nel membro Flags della struttura D3DDDICB_LOCK.
La funzione pfnLockCb attende fino a quando non viene eseguito il trasferimento (unswizzling) tra le allocazioni.
La funzione pfnLockCb richiede che il driver miniport di visualizzazione ottenga un indirizzo virtuale per l'allocazione non guidata e restituisca l'indirizzo virtuale al driver di visualizzazione in modalità utente nel membro pData di D3DDDICB_LOCK.
Il driver di visualizzazione in modalità utente restituisce l'indirizzo virtuale dell'allocazione non guidata all'applicazione nel membro pSurfData di D3DDDIARG_LOCK.