Elenchi di comandi di supporto

Questa sezione si applica solo a Windows 7 e versioni successive e Windows Server 2008 R2 e versioni successive di Windows.

Il runtime Direct3D usa i seguenti DDI Direct3D 11 per gli elenchi di comandi:

La semantica per le funzioni CommandListExecute, CalcPrivateCommandListSize, CreateCommandList e DestroyCommandList è principalmente autoesplicativa, basata su altre funzioni DDI simili e sulla documentazione dell'API per l'DDI corrispondente.

Dopo che il runtime Direct3D chiama correttamente la funzione CreateCommandList o RecycleCreateCommandList nel contesto posticipato specificato nel membro hDeferredContext della struttura D3D11DDIARG_CREATECOMMANDLIST a cui punta il parametro pCreateCommandList , il runtime Direct3D esegue la sequenza di distruzione seguente nel contesto posticipato:

  1. Il runtime Direct3D "chiude" tutti gli handle di oggetti posticipati aperti. Si noti che questi handle potrebbero essere ancora associati al contesto posticipato.

  2. Il runtime elimina il contesto posticipato.

Durante la chiamata a CreateCommandList o RecycleCreateCommandList, tutte le chiamate effettuate dal driver alle funzioni di callback DDI di aggiornamento dello stato continuano a divulgare lo stato corrente del contesto posticipato. Tuttavia, durante la "chiusura" e la distruzione del contesto posticipato, tutte le chiamate all'aggiornamento dello stato DDI riflettono che nulla è associato(ovvero, immediatamente dopo la chiamata a CreateCommandList o RecycleCreateCommandList, tutto è implicitamente non associato).

Un contesto posticipato può essere abbandonato in modo esplicito dall'applicazione o a causa di una condizione di errore dall'API o dal driver. Per questi casi, il runtime Direct3D esegue la sequenza seguente:

  1. Il runtime Direct3D chiama la funzione AbandonCommandList del driver.

  2. Il runtime unbinds gestisce dal contesto posticipato uno per uno.

  3. Il runtime "chiude" tutti gli handle di oggetti posticipati aperti.

  4. Il runtime si ripete o elimina il contesto posticipato.

La sequenza precedente è simile alla sequenza di distruzione di un contesto immediato. La chiamata alla funzione AbandonCommandList del driver consente al driver di applicare lo stato in qualsiasi modo preferito dal driver.

Durante la chiamata alla funzione CommandListExecute del driver, il driver deve eseguire la transizione dello stato del contesto posticipato per renderlo equivalente allo stato in cui è stato creato il dispositivo. Questa operazione è nota anche come operazione di stato chiaro. Durante la chiamata alla funzione CommandListExecute del driver, tuttavia, tutte le chiamate effettuate dal driver alle funzioni di callback DDI di aggiornamento dello stato riflettono ancora lo stato di quello associato durante l'ultima chiamata DDI a una funzione driver. Durante la chiamata DDI successiva a una funzione driver, tutte le chiamate effettuate dal driver alle funzioni di callback DDI di aggiornamento dello stato mostrano lo stato corrente come completamente vuoto, che riflette la transizione dello stato implicita da CommandListExecute. Questo fatto differisce leggermente dalla semantica tipica e dal comportamento delle funzioni di callback DDI di aggiornamento dello stato. Se il driver aveva chiamato una funzione di callback DDI di aggiornamento stato durante una chiamata a una delle funzioni SetShader del driver, la funzione di callback DDI di aggiornamento dello stato visualizzerebbe come già associato il nuovo shader associato. Questa divergenza del comportamento di callback DDI di aggiornamento dello stato offre maggiore flessibilità al driver per riflettere lo stato precedente durante CommandListExecute.

L'API Direct3D versione 11 garantisce che nessuna query sia stata modificata (ovvero queryBegin o QueryEnd ) dall'elenco di comandi e sia stata "avviata" solo dal contesto che tenta di eseguire l'elenco di comandi. L'API garantisce inoltre che non venga eseguito alcun elenco di comandi che ha registrato la mappa di una risorsa dinamica in un contesto con la stessa risorsa attualmente mappata. Prima che un'applicazione chiami la funzione FinishCommandList , il runtime Direct3D chiama la funzione QueryEnd e ResourceUnmap DDI del driver in qualsiasi query o risorsa dinamica che contiene ancora una query avviata o una risorsa mappata aperta perché FinishCommandList termina implicitamente gli intervalli di query e annulla il mapping di qualsiasi risorsa mappata.

Ottimizzazione per elenchi di comandi di piccole dimensioni

Un'ottimizzazione del riciclo della memoria per elenchi di comandi di piccole quantità di memoria può essere importante per ridurre la contesa tra le chiamate di funzione DDI dell'elenco di comandi e ridurre il sovraccarico dell'elaborazione delle chiamate necessarie per gli elenchi di comandi. Il sovraccarico di elaborazione che è inerant in ogni elenco di comandi è significativo. Questa ottimizzazione è destinata agli elenchi di comandi in cui il sovraccarico di elaborazione necessario per gli elenchi di comandi domina il tempo della CPU e lo spazio di memoria necessari per gli elenchi di comandi. Un elenco di comandi di quantità di memoria ridotta è, ad esempio, un singolo comando grafico, ad esempio CopyResource. La quantità di memoria necessaria per CopyResource è due puntatori. Tuttavia, CopyResource richiede comunque la stessa quantità di elaborazione delle chiamate all'elenco di comandi come elenco di comandi di grandi dimensioni di memoria. Quando vengono generati elenchi di comandi di quantità di memoria ridotta ad alta frequenza, il sovraccarico di elaborazione richiesto per il runtime per chiamare le funzioni CreateCommandList del driver, DestroyCommandList, CreateDeferredContext e DestroyDevice(D3D10) (per il contesto posticipato) diventa sempre più importante. La memoria a cui si fa riferimento è memoria di sistema che contiene strutture di dati driver, che include la memoria per gli handle DDI.

La funzione RecycleCommandList del driver deve notificare al driver quando gli handle del driver non vengono usati (ma non sono ancora eliminati) e quando vengono riutilizzati gli handle del driver precedentemente inutilizzati. Questa notifica si applica sia agli handle del contesto posticipato che dell'elenco dei comandi. L'unica memoria a cui deve essere riciclato il driver è la memoria a cui punta l'handle DDI. Anche se l'obiettivo di RecycleCommandList consiste nel riciclare la memoria associata all'handle, per l'efficienza il driver ha una flessibilità completa per selezionare e scegliere quale memoria riciclare. Il driver non può modificare le dimensioni dell'area di memoria in cui l'elenco di comandi di contesto immediato gestisce i punti. Questa dimensione è il valore restituito di CalcPrivateCommandListSize. Il driver non può anche modificare le dimensioni dell'area di memoria in cui l'elenco dei comandi di contesto elenca i punti di gestione locali. Questa dimensione è il valore restituito di CalcDeferredContextHandleSize.

Le funzioni DDI DDI di RicicloCreateCommandList e RecycleCreateDeferredContext DDI devono restituire codici di errore non aggiornati in memoria come E_OUTOFMEMORY valori HRESULT. Queste funzioni non forniscono tali codici di errore tramite chiamate alla funzione pfnSetErrorCb . Questo requisito del driver impedisce al runtime di dover usare la sincronizzazione a livello di dispositivo per watch per errori di contesto immediati da queste funzioni di driver di tipo create. L'analisi di questi errori sarebbe un'origine di contesa irreversibile per elenchi di comandi di quantità di memoria ridotta.

Le distinzione tra le funzioni RecycleDestroyCommandList, RecycleCommandList e RecycleCreateCommandList del driver sono importanti. Le loro funzionalità includono quanto segue.

RicicloDestroyCommandList

Il runtime chiama la funzione RecycleDestroyCommandList del driver per notificare al driver che è necessaria la distruzione leggera. Ovvero, il driver non deve ancora deassegnare la memoria per l'handle dell'elenco di comandi DDI. La funzione RecycleDestroyCommandList del driver è threadata gratuitamente come la funzione DestroyCommandList del driver.

RecycleCommandList

La funzione RecycleCommandList del driver informa il driver che il runtime ha integrato un handle dell'elenco di comandi nella cache del contesto posticipato. La funzione fornisce quindi al driver l'opportunità di integrare la memoria associata all'elenco di comandi nella cache del contesto posticipato. Il runtime chiama la funzione RecycleCommandList del driver dal thread di contesto posticipato. La funzione RecycleCommandList DDI riduce la necessità del driver di eseguire la sincronizzazione del proprio.

RicicloCreateCommandList

Il runtime chiama la funzione RecycleCreateCommandList del driver per rendere un handle DDI precedentemente inutilizzato completamente valido.

Queste funzioni DDI di riciclo offrono opportunità di ottimizzazione per facilitare il riciclo delle risorse per elenchi di comandi di piccole dimensioni di memoria. Lo pseudocode seguente mostra l'implementazione del runtime tramite il flusso di chiamate di funzione dall'API all'DDI :

::FinishCommandList()
{
  // Empty InterlockedSList, integrating into the cache
  Loop { DC::pfnRecycleCommandList }

  If (Previously Destroyed CommandList Available)
 { IC::pfnRecycleCreateCommandList }
 else
  {
    IC::pfnCalcPrivateCommandListSize
    IC::pfnCreateCommandList
    IC::pfnCalcDeferredContextHandleSize(D3D11DDI_HT_COMMANDLIST)
  }

  Loop { DC::pfnDestroy* (context-local handle destroy) }

  IC::pfnRecycleCreateDeferredContext
}
...
Sporadic: DC::pfnCreate* (context-local open during first-bind per CommandList)

CommandList::Destroy()
{
  // If DC still alive, almost always recycle:
  If (DC still alive)
 { IC::pfnRecycleDestroyCommandList }
  Else
 { IC::pfnDestroyCommandList }
  // Add to InterlockedSList
}

Il diagramma dello stato seguente mostra la validità di un handle di comando DDI di contesto immediato. Lo stato verde rappresenta un handle che può essere usato con CommandListExecute.

Diagramma che illustra gli stati di validità di un handle di comando DDI DDI immediato.