Limitazioni del controllo del flusso

Le istruzioni di controllo del flusso dello shader pixel hanno limiti che influiscono sul numero di livelli di annidamento che possono essere inclusi nelle istruzioni. Esistono inoltre alcune limitazioni per l'implementazione del controllo del flusso per pixel con istruzioni sulla sfumatura.

Nota

Quando si usano i profili shader *_4_0_level_9_x HLSL, si usano in modo implicito i profili shader Model 2.x per supportare l'hardware compatibile con Direct3D 9. I profili del modello shader 2.x supportano un comportamento di controllo del flusso più limitato rispetto ai profili modello shader 4.x e versioni successive.

 

Numero di profondità istruzioni pixel shader

ps_2_0 non supporta il controllo del flusso. Di seguito sono elencate le limitazioni per le altre versioni del pixel shader.

Conteggio profondità istruzioni per ps_2_x

Ogni istruzione viene conteggiato rispetto a uno o più limiti di profondità annidamento. Nella tabella seguente viene elencato il numero di profondità aggiunto o sottratto da ogni istruzione dalla profondità esistente.

Istruzione Annidamento statico Annidamento dinamico annidamento loop/rep annidamento delle chiamate
se bool - ps 1 0 0 0
if_comp - ps 0 1 0 0
se pred - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(se pred - ps o if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

Profondità annidamento

La profondità di annidamento definisce il numero di istruzioni che è possibile chiamare tra loro. Ogni tipo di istruzione ha uno o più limiti di annidamento, come indicato nella tabella seguente.

Tipo di istruzione Massimo
Annidamento statico 24 se (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 in caso contrario
Annidamento dinamico Da 0 a 24, vedere D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth
annidamento rep Da 0 a 4, vedere D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth
annidamento delle chiamate Da 0 a 4, vedere D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (indipendente dal limite di rep)

 

Conteggio profondità istruzioni per ps_2_sw

Ogni istruzione viene conteggiato rispetto a uno o più limiti di profondità annidamento. Questa tabella mostra il numero di profondità che ogni istruzione aggiunge o sottrae dalla profondità esistente.

Istruzione Annidamento statico Annidamento dinamico annidamento loop/rep annidamento delle chiamate
se bool - ps 1 0 0 0
se pred - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(se pred - ps o if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
loop - ps n/d n/d n/d n/d
endloop - ps n/d n/d n/d n/d
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

Profondità annidamento

La profondità di annidamento definisce il numero di istruzioni che possono essere chiamate tra loro. Ogni tipo di istruzione ha uno o più limiti di annidamento, come indicato nella tabella seguente.

Tipo di istruzione Massimo
Annidamento statico 24
Annidamento dinamico 24
annidamento rep 4
annidamento delle chiamate 4

 

Conteggio profondità istruzione per ps_3_0

Ogni istruzione conta su uno o più limiti di profondità annidamento. Questa tabella mostra il numero di profondità che ogni istruzione aggiunge o sottrae dalla profondità esistente.

Istruzione Annidamento statico Annidamento dinamico ciclo/annidamento del repository annidamento delle chiamate
if bool - ps 1 0 0 0
se pred - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(se pred - ps o if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
ciclo - ps 0 0 1 0
endloop - ps 0 0 -1 0
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
chiamata - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

Profondità annidamento

La profondità di annidamento definisce il numero di istruzioni che possono essere chiamate tra loro. Ogni tipo di istruzione ha uno o più limiti di annidamento, come indicato nella tabella seguente.

Tipo di istruzione Massimo
Annidamento statico 24
Annidamento dinamico 24
annidamento loop/rep 4
annidamento delle chiamate 4

 

Conteggio profondità istruzioni per ps_3_sw

Ogni istruzione viene conteggiato rispetto a uno o più limiti di profondità annidamento. Questa tabella mostra il numero di profondità che ogni istruzione aggiunge o sottrae dalla profondità esistente.

Istruzione Annidamento statico Annidamento dinamico annidamento loop/rep annidamento delle chiamate
se bool - ps 1 0 0 0
se pred - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(se pred - ps o if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
loop - ps 0 0 1 0
endloop - ps 0 0 -1 0
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

Profondità annidamento

La profondità di annidamento definisce il numero di istruzioni che possono essere chiamate tra loro. Ogni tipo di istruzione ha uno o più limiti di annidamento, come indicato nella tabella seguente.

Tipo di istruzione Massimo
Annidamento statico 24
Annidamento dinamico 24
annidamento loop/rep 4
annidamento delle chiamate 4

 

Interazione del controllo del flusso di Per-Pixel con sfumature dello schermo

Il set di istruzioni pixel shader include diverse istruzioni che producono o usano sfumature di quantità rispetto allo spazio dello schermo x e y. L'uso più comune per le sfumature consiste nel calcolare calcoli di livello di dettaglio per il campionamento delle trame e, in caso di filtro anisotropico, selezionando campioni lungo l'asse dell'anisotropia. In genere, le implementazioni hardware eseguono il pixel shader su più pixel contemporaneamente (ad esempio una griglia 2x2), in modo che le sfumature di quantità calcolate nello shader possano essere ragionevolmente approssimative come delta dei valori allo stesso punto di esecuzione in pixel adiacenti.

Quando il controllo del flusso è presente in uno shader, il risultato di un calcolo della sfumatura richiesto all'interno di un determinato percorso di ramo è ambiguo quando i pixel adiacenti possono eseguire percorsi di controllo del flusso separati. Pertanto, è considerato illegale usare qualsiasi operazione pixel shader che richiede un calcolo della sfumatura in una posizione all'interno di un costrutto di controllo del flusso che può variare in pixel per una determinata primitiva da rasterizzare.

Tutte le istruzioni del pixel shader vengono partizionate in tali operazioni consentite e in quelle non consentite all'interno del controllo del flusso:

  • Scenario A: Operazioni non consentite all'interno del controllo del flusso che possono variare tra i pixel in una primitiva. Queste includono le operazioni elencate nella tabella seguente.

    Istruzione È consentito nel controllo del flusso quando:
    texld - ps_2_0 e up, texldb - ps e texldp - ps Viene usato un registro temporaneo per la coordinata della trama.
    dsx - ps e dsy - ps Per l'operando viene utilizzato un registro temporaneo.

     

  • Scenario B: operazioni consentite ovunque. Queste includono le operazioni elencate nella tabella seguente.

    Istruzione È consentito ovunque:
    texld - ps_2_0 e up, texldb - ps e texldp - ps Viene usata una quantità di sola lettura per la coordinata della trama (può variare per pixel, ad esempio le coordinate della trama interpolate).
    dsx - ps e dsy - ps Viene usata una quantità di sola lettura per l'operando di input (può variare per pixel, ad esempio le coordinate della trama interpolate).
    texldl - ps L'utente fornisce un livello di dettaglio come argomento, quindi non ci sono sfumature e quindi nessun problema con il controllo del flusso.
    texldd - ps L'utente fornisce sfumature come argomenti di input, pertanto non esiste alcun problema con il controllo del flusso.

     

Queste restrizioni vengono applicate rigorosamente nella convalida dello shader. Scenari con una condizione di ramo simile a quella in cui si dirama in modo coerente una primitiva, anche se un operando nell'espressione della condizione è una quantità calcolata da pixel shader, tuttavia non rientrano nello scenario A e non sono consentiti. Analogamente, gli scenari in cui le sfumature vengono richieste su una quantità calcolata di shader x dall'interno del controllo del flusso dinamico, ma dove sembra che x non venga modificato in nessuno dei rami, tuttavia rientrano nello scenario A e non sono consentiti.

Il predicato è incluso in queste restrizioni sul controllo del flusso, in modo che le implementazioni rimangano libere di interscambiare in modo semplice l'implementazione delle istruzioni di ramo con istruzioni predicate.

L'utente può usare le istruzioni degli scenari A e B insieme. Si supponga, ad esempio, che l'utente abbia bisogno di un campione di trama anisotropica in base a una coordinata di trama calcolata dello shader; Tuttavia, il carico della trama è necessario solo per i pixel che soddisfano alcune condizioni per pixel. Per soddisfare questi requisiti, l'utente può calcolare la coordinata della trama per tutti i pixel, al di fuori del controllo del flusso variabile per pixel, calcolando immediatamente i gradienti usando dsx - ps e dsy - istruzioni ps . Quindi, all'interno di un bool per pixel - ps/endif - blocco ps , l'utente può usare texldd - ps (caricamento trama con sfumature fornite dall'utente), passando le sfumature precalcolate. Un altro modo per descrivere questo modello di utilizzo è che, mentre tutti i pixel nella primitiva hanno dovuto calcolare le coordinate della trama ed essere coinvolti con il calcolo della sfumatura, solo i pixel necessari per campionare una trama lo hanno effettivamente fatto.

Indipendentemente da queste regole, l'onere è ancora sull'utente per assicurarsi che prima di calcolare qualsiasi sfumatura (o eseguire un campione di trama che calcola in modo implicito una sfumatura), il registro contenente i dati di origine deve essere stato inizializzato prima per tutti i percorsi di esecuzione. L'inizializzazione dei registri temporanei non viene convalidata o applicata in generale.

Istruzioni per pixel shader