Temporizzazione (grafica Direct3D 12)
Questa sezione illustra l'esecuzione di query sui timestamp e la calibrazione dei contatori timestamp GPU e CPU.
Frequenza della marca temporale
L'applicazione può eseguire una query sulla frequenza del timestamp GPU in base alla coda dei comandi (vedere il metodo ID3D12CommandQueue::GetTimestampFrequency).
La frequenza restituita viene misurata in Hz (tic/sec). Se la coda di comandi specificata non supporta i timestamp (vedere la tabella nella sezione Query), l'API ha esito negativo e restituisce E_FAIL. D3D12_COMMAND_LIST_TYPE_DIRECT e D3D12_COMMAND_LIST_TYPE_COMPUTE sono sempre in grado di supportare i timestamp. D3D12_COMMAND_LIST_TYPE_COPY supporta i timestamp opzionalmente se il membro D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported è TRUE.
Calibrazione del timestamp
D3D12 consente alle applicazioni di correlare i risultati ottenuti dalle query timestamp con i risultati ottenuti dalla chiamata QueryPerformanceCounter
. Questa operazione è abilitata dalla chiamata ID3D12CommandQueue::GetClockCalibration.
Un timestamp viene campionato dalla GPU nel momento in cui ha completato tutto il carico di lavoro precedente. È lo stesso comportamento adottato da Direct3D 11 (vedere D3D11_QUERY_TIMESTAMP nella specifica funzionale direct3D 11.3 su GitHub). Ciò significa che le query timestamp sono un'operazione bottom-of-pipe (BOP) in Direct3D 12.
GetClockCalibration campiona il contatore timestamp DELLA GPU per una determinata coda di comandi ed esegue il campionamento del contatore della CPU tramite QueryPerformanceCounter
quasi contemporaneamente. Anche in questo caso, questa API ha esito negativo (restituendo E_FAIL) se la coda di comandi specificata non supporta i timestamp (vedere la tabella nell'argomento query ).
Si noti che i contatori dei timestamp della GPU e della CPU non sono necessariamente direttamente correlati alla velocità di clock di questi processori, ma si basano invece sui tick di timestamp.
Query di timestamp
È possibile ottenere timestamp come parte di un elenco di comandi (anziché una chiamata lato CPU in una coda di comandi) tramite query timestamp. Per ulteriori informazioni sulle query in generale, vedere Queries.
Tutte le query timestamp usano il tipo D3D12_QUERY_TYPE_TIMESTAMP per la query vera e propria. Tuttavia, a causa delle limitazioni hardware, D3D12_COMMAND_LIST_TYPE_DIRECT e D3D12_COMMAND_LIST_TYPE_COMPUTE usare un D3D12_QUERY_HEAP_TYPE diverso da quello usato da D3D12_COMMAND_LIST_TYPE_COPY.
Le code dirette e di calcolo usano D3D12_QUERY_HEAP_TYPE_TIMESTAMP.
Le code di copia utilizzano D3D12_QUERY_HEAP_TYPE_COPY_QUEUE_TIMESTAMP.
Le query della coda di copia sono supportate solo se il membro D3D12_FEATURE_DATA_D3D12_OPTIONS3::CopyQueueTimestampQueriesSupported è TRUE.
Le query di timestamp, una volta risolte tramite ID3D12GraphicsCommandList::ResolveQueryData, sono un UINT64 che rappresenta i tick, come viene restituito da ID3D12CommandQueue::GetClockCalibration, e quindi deve essere diviso per la frequenza della coda per ottenere la lunghezza in secondi.
Importante
Per l'accuratezza, usare l'aritmetica a virgola mobile quando si calcolano intervalli di secondi o millisecondi di timestamp. Ad esempio, usare queriedTicks / (double)Frequency
anziché queriedTicks / Frequency
.