Condividi tramite


Procedura dettagliata: utilizzo della diagnostica grafica per eseguire il debug di un compute shader

In questa procedura dettagliata viene illustrato come utilizzare gli strumenti di diagnostica grafiche di Visual Studio per esaminare il compute shader che genera risultati errati.

In questa procedura dettagliata vengono illustrate le attività seguenti:

  • Utilizzo della finestra Elenco eventi grafici per individuare le origini potenziali del problema.

  • Utilizzo di Stack di chiamate eventi grafici per determinare quale compute shader viene eseguito da un evento DirectCompute Dispatch.

  • Utilizzo della finestra Fasi pipeline grafica e del debugger HLSL per esaminare il compute shader che è l'origine del problema.

Scenario

In questo scenario è stata scritta una simulazione di dinamica del fluidi in cui viene utilizzato DirectCompute per eseguire le parti con calcoli complessi dell'aggiornamento della simulazione. Quando l'applicazione viene eseguita, il rendering del dataset e l'interfaccia utente sono corretti, ma la simulazione non si comporta come previsto. Utilizzando la diagnostica della grafica, è possibile acquisire il problema in un log della grafica in modo da poter eseguire il debug dell'applicazione. Il problema si presenta nel seguente modo nell'app:

Il comportamento del fluido simulato non è corretto.

Per informazioni su come acquisire i problemi di grafica in un log di grafica, vedere Cattura informazioni grafica.

Analisi

È possibile utilizzare gli strumenti di diagnostica della grafica per caricare il file di log della grafica, in modo da poter controllare i frame acquisiti.

Per esaminare un frame nel log di grafica

  1. In Visual Studio caricare un log di grafica contenente un frame che mostra i risultati di simulazione errati. Verrà visualizzata una nuova scheda della diagnostica della grafica in Visual Studio. Nella parte superiore di questa scheda è presente l'output della destinazione di rendering del frame selezionato. Nella parte inferiore è presente Elenco frame che visualizza un'immagine di anteprima di ogni frame acquisito.

  2. In Elenco frame selezionare un frame che indica il comportamento errato di simulazione. Anche se sembra che l'errore si trovi nel codice di simulazione e non nel codice di rendering, è comunque necessario scegliere un frame poiché gli eventi DirectCompute vengono acquisiti un frame alla volta, insieme agli eventi Direct3D. In questo scenario il log della grafica ha l'aspetto seguente:

    Log grafico in Visual Studio.

Dopo avere selezionato un frame in cui viene illustrato il problema, è possibile utilizzare l'Elenco eventi grafici per diagnosticarlo. L'Elenco eventi grafici contiene un evento per ogni chiamata di DirectCompute e Direct3D API effettuata durante il frame attivo, ad esempio le chiamate API per eseguire un calcolo su GPU o per eseguire il rendering del dataset o dell'interfaccia utente. In questo caso, vengono presi in considerazione gli eventi Dispatch che rappresentano parti della simulazione eseguita nella GPU.

Per trovare l'evento di invio per l'aggiornamento di simulazione

  1. Sulla barra degli strumenti Diagnostica grafica scegliere Elenco eventi per aprire la finestra Elenco eventi grafici.

  2. Controllare Elenco eventi grafici relativamente all'evento di disegno tramite cui viene eseguito il rendering del dataset. Per semplificare questa procedura, immettere Disegno nella casella Cerca nell'angolo superiore destro della finestra Elenco eventi grafici. In questo modo l'elenco viene filtrato in modo da contenere solo gli eventi nei cui titoli compare "Disegno". In questo scenario viene rilevato che si sono verificati questi eventi di disegno:

    Elenco eventi con eventi di disegno.

  3. Spostarsi in ogni evento di disegno durante la visualizzazione della destinazione di rendering nella scheda dei documenti del log di grafica.

  4. Arrestare l'operazione quando nella destinazione di rendering viene visualizzato innanzitutto il set di dati di cui è stato eseguito il rendering. In questo caso il rendering del dataset viene eseguito nel primo evento di disegno. L'errore nella simulazione è indicato:

    Questo evento di disegno esegue il rendering del set di dati di simulazione.

  5. A questo punto, controllare Elenco eventi grafici relativamente all'evento Dispatch tramite cui viene aggiornata la simulazione. Poiché è probabile che la simulazione venga aggiornata prima che venga eseguito il rendering, è possibile concentrarsi prima sugli eventi Dispatch che si verificano prima dell'evento di disegno che esegue il rendering dei risultati. Per semplificare questa procedura, modificare la casella Cerca per leggere Draw;Dispatch;CSSetShader(. Ciò consente di filtrare l'elenco in modo che contenga anche Dispatch e gli eventi CSSetShader oltre agli eventi di disegno. In questo scenario viene rilevato che diversi eventi Dispatch si sono verificati prima dell'evento di disegno:

    Elenco eventi con eventi di disegno, invio e CSSetShader

Una volta compresi i pochi dei tanti potenziali eventi Dispatch che potrebbero corrispondere al problema, è possibile esaminarli in modo più dettagliato.

Per determinare quale compute shader esegue una chiamata di invio

  1. Sulla barra degli strumenti Diagnostica grafica scegliere Stack di chiamate eventi per aprire la finestra Stack di chiamate eventi grafici.

  2. A partire dall'evento di disegno tramite cui viene eseguito il rendering dei risultati di simulazione, tornare a ogni evento CSSetShader precedente. Quindi, nella finestra Stack di chiamate eventi grafici, scegliere la funzione in primo piano per individuare il sito di chiamata. Nel sito della chiamata, è possibile utilizzare il primo parametro della funzione CSSetShader per determinare quale compute shader viene eseguito dall'evento Dispatch successivo.

In questo scenario sono presenti tre coppie di eventi CSSetShader e Dispatch in ogni frame. Procedendo in ordine inverso, la terza coppia rappresenta il passaggio di integrazione (dove le particelle fluide vengono spostate effettivamente), la seconda coppia rappresenta il passaggio di forza-calcolo (dove le forze che influiscono su ogni particella vengono calcolate) e la prima coppia rappresenta il passaggio di densità-calcolo.

Per eseguire il debug del compute shader

  1. Sulla barra degli strumenti Diagnostica grafica scegliere Fasi pipeline per aprire la finestra Fasi pipeline grafica.

  2. Selezionare il terzo evento Dispatch (quello che precede immediatamente l'evento di disegno), quindi nella fase Compute shader della finestra Fasi pipeline grafica scegliere Avvia debug.

    Selezione del terzo evento di invio nell'elenco eventi.

    Il debugger di HLSL viene avviato a livello di shader che esegue l'operazione di integrazione.

  3. Esaminare il codice sorgente di compute shader per il passaggio di integrazione per ricercare l'origine dell'errore. Quando si utilizza la diagnostica della grafica per eseguire il debug del codice di compute shader di HLSL, è possibile avanzare nel codice e utilizzare altri strumenti di debug comuni quali le finestre Espressioni di controllo. In questo scenario viene determinato che non sembra essere presente alcun errore nel compute shader tramite cui viene eseguito il passaggio di integrazione.

    Debug del compute shader IntegrateCS.

  4. Per arrestare il debug del compute shader, nella barra degli strumenti Debug, scegliere Arresta debug (tastiera: MAIUSC+F5).

  5. Successivamente, selezionare il secondo evento Dispatch e avviare il debug del compute shader come eseguito nel passaggio precedente.

    Selezione del secondo evento di invio nell'elenco eventi.

    Il debugger di HLSL viene avviato a livello di shader che calcola le forze che agiscono su ogni particella fluida.

  6. Esaminare il codice sorgente di compute shader per il passaggio di forza-calcolo. In questo scenario viene determinato che l'origine dell'errore si trova in questo punto.

    Debug del compute shader semplice ForceCS.

Dopo aver definito la posizione dell'errore, è possibile arrestare il debug e modificare il codice sorgente di compute shader per calcolare correttamente la distanza tra le particelle interattive. In questo scenario si imposta semplicemente la riga float2 diff = N_position + P_position; su float2 diff = N_position - P_position;:

Codice del compute shader con correzione.

In questo scenario poiché i compute shader vengono compilati in fase di esecuzione, l'applicazione può essere riavviata solo dopo aver apportato le modifiche per osservare come influiscono sulla simulazione. Non è necessario ricompilare l'applicazione. Quando si esegue l'applicazione, si scopre che la simulazione funziona ora correttamente.

Il comportamento del fluido simulato è corretto.