Monitoraggio del contesto

Questo articolo fornisce informazioni sul monitoraggio del contesto, che consente una sincronizzazione flessibile tra motori GPU o tra core CPU e motori GPU. Un oggetto di recinzione monitorato, che è una forma avanzata di sincronizzazione del recinto, consente a un core CPU o a un motore GPU di segnalare o attendere un determinato oggetto di isolamento.

Creazione del recinto monitorato

Il runtime Direct3D crea un oggetto di isolamento monitorato chiamando il callback CreateSynchronizationObjectCb del driver in modalità utente con il tipo di oggetto di sincronizzazione D3DDDI_MONITORED_FENCE .

Viene creato un oggetto di isolamento monitorato insieme agli attributi seguenti:

  • Valore iniziale
  • Flag (specificandone il comportamento di attesa e segnalazione)

Al momento della creazione, il kernel grafico restituisce un oggetto recinto composto dagli elementi seguenti:

Elemento Descrizione
hSyncObject Handle per l'oggetto di sincronizzazione. Usato per farvi riferimento in una chiamata al kernel grafico.
FenceValueCPUVirtualAddress Mapping di sola lettura del valore di isolamento (64 bit) per la CPU. Questo indirizzo è mappato WB (memorizzabile nella cache) dal punto di vista della CPU sulle piattaforme che supportano la coesistenza di I/O, UC (non memorizzato nella cache) in altre piattaforme. Consente alla CPU di tenere traccia dello stato di avanzamento del recinto semplicemente leggendo questa posizione di memoria. La CPU non è autorizzata a scrivere in questa posizione di memoria. Per segnalare il limite, la CPU è necessaria per chiamare SignalSynchronizationObjectFromCpuCb. Gli adattatori che supportano IoMmu devono usare questo indirizzo per l'accesso alla GPU. L'indirizzo viene mappato come lettura/scrittura in questo caso.
FenceValueGPUVirtualAddress Mapping di lettura/scrittura del valore di isolamento (64 bit) per la GPU. Questo indirizzo viene mappato come richiede la coesistenza di I/O sulle piattaforme che lo supportano. Per segnalare il limite, la GPU può scrivere direttamente in questo indirizzo virtuale GPU. Le GPU IoMmu non devono usare questo indirizzo.

Il valore di recinto è un valore a 64 bit con i rispettivi indirizzi virtuali allineati su un limite a 64 bit. Le GPU devono dichiarare se sono in grado di aggiornare in modo atomico i valori a 64 bit come visibili dalla CPU tramite il flag aggiunto DXGK_VIDSCHCAPS::No64BitAtomics . Se una GPU è in grado di aggiornare solo i valori a 32 bit in modo atomico, il sistema operativo gestisce automaticamente il case wraparound di isolamento. Tuttavia, inserisce una restrizione che i valori di attesa e di isolamento dei segnali in sospeso non possono essere più di UINT_MAX/2 rispetto all'ultimo valore di recinto segnalato.

Segnale GPU

Se un motore GPU non è in grado di scrivere in un recinto monitorato usando l'indirizzo virtuale, il driver in modalità utente usa il callback SignalSynchronizationObjectFromGpuCb per accodare un pacchetto di segnale software al contesto GPU.

Per segnalare il limite dalla GPU, la UMD inserisce un comando di scrittura di isolamento in un flusso di comandi di contesto direttamente senza passare attraverso la modalità kernel. Il meccanismo in base al quale il kernel monitora lo stato di avanzamento del recinto varia a seconda che un determinato motore GPU supporti l'implementazione di base o avanzata del recinto monitorato.

Quando un buffer dei comandi completa l'esecuzione nella GPU, il kernel grafico:

  • Esamina l'elenco di oggetti di isolamento con attese in sospeso che potrebbero essere segnalate per questo processo
  • Legge il valore di recinto corrente
  • Determina se sono presenti attese che devono essere annullate.

Attesa GPU

Per attendere un recinto monitorato in un motore GPU, il UMD deve prima scaricare il buffer dei comandi in sospeso, quindi chiamare WaitForSynchronizationObjectFromGpuCb specificando l'oggetto di isolamento (hSyncObject) e il valore di isolamento in attesa. Il kernel grafico accoda la dipendenza al database interno, quindi restituisce immediatamente all'UMD in modo che possa continuare a accodare il lavoro dietro l'operazione di attesa. I buffer dei comandi inviati dopo l'operazione di attesa non vengono pianificati per l'esecuzione finché l'operazione di attesa non viene soddisfatta.

Segnale CPU

Il callback SignalSynchronizationObjectFromCpuCb è stato aggiunto per consentire alla CPU di segnalare un oggetto di isolamento monitorato. Quando la CPU segnala un oggetto recinto monitorato, il kernel grafico aggiorna la posizione di memoria di isolamento con il valore segnalato. Questo valore diventa immediatamente visibile a qualsiasi lettore in modalità utente e annulla immediatamente eventuali attese soddisfatte.

Attesa CPU

È stato aggiunto un callback WaitForSynchronizationObjectFromCpuCb per consentire alla CPU di attendere un oggetto di isolamento monitorato. Sono disponibili due forme di operazioni di attesa. Nella prima maschera WaitForSynchronizationObjectFromCpuCb si blocca finché l'attesa non viene soddisfatta. Nel secondo modulo WaitForSynchronizationObjectFromCpuCb accetta un handle per un evento cpu segnalato dopo che la condizione di attesa viene soddisfatta.