Flusssteuerungseinschränkungen
Anweisungen zur Steuerung des Pixel-Shaders haben Grenzwerte, die sich darauf auswirken, wie viele Ebenen der Schachtelung in den Anweisungen enthalten sein können. Darüber hinaus gibt es einige Einschränkungen für die Implementierung der Flusssteuerung pro Pixel mit Farbverlaufsanweisungen.
Hinweis
Wenn Sie die *_4_0_level_9_x HLSL-Shaderprofile verwenden, verwenden Sie implizit die Profile des Shadermodells 2.x , um Direct3D 9-fähige Hardware zu unterstützen. Shadermodell 2.x-Profile unterstützen ein stärker eingeschränktes Ablaufsteuerungsverhalten als die Profile shader Model 4.x und höher.
Anzahl der Pixel-Shaderanweisungen
ps_2_0 unterstützt keine Ablaufsteuerung. Die Einschränkungen für die anderen Pixel-Shaderversionen sind unten aufgeführt.
Anzahl der Befehlstiefe für ps_2_x
Jede Anweisung zählt für mindestens eine Schachtelungstiefe. In der folgenden Tabelle ist die Tiefenanzahl aufgeführt, die von jeder Anweisung hinzugefügt oder von der vorhandenen Tiefe subtrahiert wird.
Anweisung | Statische Schachtelung | Dynamische Schachtelung | Schleifen-/Rep-Schachtelung | Schachteln von Aufrufen |
---|---|---|---|---|
if bool - ps | 1 | 0 | 0 | 0 |
if_comp – ps | 0 | 1 | 0 | 0 |
if pred - ps | 0 | 1 | 0 | 0 |
else – ps | 0 | 0 | 0 | 0 |
endif – ps | -1(if bool - ps) | -1(wenn pred - ps oder 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 |
Schachtelungstiefe
Die Schachtelungstiefe definiert die Anzahl der Anweisungen, die von innen aufgerufen werden können. Jeder Befehlstyp weist mindestens einen Schachtelungsgrenzwerte auf, wie in der folgenden Tabelle angegeben.
Anweisungstyp | Maximum |
---|---|
Statische Schachtelung | 24 if (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 andernfalls |
Dynamische Schachtelung | 0 bis 24, siehe D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth |
Schachtelung des Vertreters | 0 bis 4, siehe D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth |
Schachteln von Aufrufen | 0 bis 4, siehe D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (unabhängig vom Wiederholungslimit) |
Anweisungstiefe für ps_2_sw
Jede Anweisung zählt für mindestens eine Schachtelungstiefe. Diese Tabelle zeigt die Tiefenanzahl, die jede Anweisung hinzufügt oder von der vorhandenen Tiefe subtrahiert.
Anweisung | Statische Schachtelung | Dynamische Schachtelung | Schleifen-/Rep-Schachtelung | Schachteln von Aufrufen |
---|---|---|---|---|
if bool - ps | 1 | 0 | 0 | 0 |
if 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(wenn pred - ps oder if_comp - ps) | 0 | 0 |
rep – ps | 0 | 0 | 1 | 0 |
endrep – ps | 0 | 0 | -1 | 0 |
Schleife – ps | – | – | – | – |
endloop – ps | – | – | – | – |
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 |
Schachtelungstiefe
Die Schachtelungstiefe definiert die Anzahl von Anweisungen, die von innen aufgerufen werden können. Jeder Anweisungstyp weist einen oder mehrere Schachtelungsgrenzwerte auf, wie in der folgenden Tabelle angegeben.
Anweisungstyp | Maximum |
---|---|
Statisches Schachteln | 24 |
Dynamische Schachtelung | 24 |
Rep-Schachtelung | 4 |
Schachteln von Aufrufen | 4 |
Anzahl der Anweisungstiefe für ps_3_0
Jede Anweisung zählt für mindestens eine Schachtelungstiefe. In dieser Tabelle wird die Tiefenanzahl angezeigt, die von jeder Anweisung hinzugefügt oder von der vorhandenen Tiefe subtrahiert wird.
Anweisung | Statisches Schachteln | Dynamische Schachtelung | Schleifen-/Rep-Schachtelung | Schachteln von Aufrufen |
---|---|---|---|---|
if bool – ps | 1 | 0 | 0 | 0 |
if 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(wenn pred - ps oder if_comp - ps) | 0 | 0 |
rep – ps | 0 | 0 | 1 | 0 |
endrep – ps | 0 | 0 | -1 | 0 |
Schleife : 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 |
Schachtelungstiefe
Die Schachtelungstiefe definiert die Anzahl von Anweisungen, die von innen aufgerufen werden können. Jeder Anweisungstyp weist einen oder mehrere Schachtelungsgrenzwerte auf, wie in der folgenden Tabelle angegeben.
Anweisungstyp | Maximum |
---|---|
Statisches Schachteln | 24 |
Dynamische Schachtelung | 24 |
Schleifen-/Rep-Schachtelung | 4 |
Schachteln von Aufrufen | 4 |
Anzahl der Anweisungstiefe für ps_3_sw
Jede Anweisung zählt für mindestens eine Schachtelungstiefe. In dieser Tabelle wird die Tiefenanzahl angezeigt, die von jeder Anweisung hinzugefügt oder von der vorhandenen Tiefe subtrahiert wird.
Anweisung | Statisches Schachteln | Dynamische Schachtelung | Schleifen-/Rep-Schachtelung | Schachteln von Aufrufen |
---|---|---|---|---|
if bool – ps | 1 | 0 | 0 | 0 |
if 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(wenn pred - ps oder if_comp - ps) | 0 | 0 |
rep – ps | 0 | 0 | 1 | 0 |
endrep – ps | 0 | 0 | -1 | 0 |
Schleife : 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 |
Schachtelungstiefe
Die Schachtelungstiefe definiert die Anzahl der Anweisungen, die von innen aufgerufen werden können. Jeder Befehlstyp weist mindestens einen Schachtelungsgrenzwerte auf, wie in der folgenden Tabelle angegeben.
Anweisungstyp | Maximum |
---|---|
Statische Schachtelung | 24 |
Dynamische Schachtelung | 24 |
Schleifen-/Rep-Schachtelung | 4 |
Schachteln von Aufrufen | 4 |
Interaktion von Per-Pixel Flusssteuerung mit Bildschirmverläufen
Der Pixel-Shader-Befehlssatz enthält mehrere Anweisungen, die Farbverläufe von Größen in Bezug auf den Bildschirmraum x und y erzeugen oder verwenden. Die am häufigsten verwendete Verwendung für Farbverläufe ist die Berechnung von Detailgradberechnungen für texturierte Stichprobenentnahmen und im Fall der anisotropen Filterung die Auswahl von Stichproben entlang der Achse der Anisotropie. In der Regel führen Hardwareimplementierungen den Pixel-Shader gleichzeitig auf mehreren Pixeln (z. B. einem 2x2-Raster) aus, sodass Gradienten der im Shader berechneten Mengen relativ als Deltas der Werte am gleichen Ausführungspunkt in benachbarten Pixeln angenähert werden können.
Wenn die Flusssteuerung in einem Shader vorhanden ist, ist das Ergebnis einer Farbverlaufsberechnung, die innerhalb eines angegebenen Branchpfads angefordert wird, mehrdeutig, wenn benachbarte Pixel separate Flusssteuerungspfade ausführen können. Daher gilt es als unzulässig, jeden Pixel-Shader-Vorgang zu verwenden, der eine Farbverlaufsberechnung an einer Stelle anfordert, die sich in einem Flusssteuerungskonstrukt befindet, das für ein bestimmtes Grundelement, das gerastert wird, pixelübergreifend variieren kann.
Alle Pixel-Shaderanweisungen werden in die vorgänge unterteilt, die zulässig sind, und in diejenigen, die innerhalb der Flusssteuerung nicht zulässig sind:
Szenario A: Vorgänge, die in der Ablaufsteuerung nicht zulässig sind und sich in den Pixeln eines Grundtyps unterscheiden können. Dazu gehören die in der folgenden Tabelle aufgeführten Vorgänge.
Anweisung Ist in der Flusssteuerung zulässig, wenn: texld - ps_2_0 und höher, texldb - ps und texldp - ps Für die Texturkoordinate wird ein temporäres Register verwendet. dsx – ps und dsy – ps Für den Operanden wird ein temporäres Register verwendet. Szenario B: Vorgänge, die überall zulässig sind. Dazu gehören die in der folgenden Tabelle aufgeführten Vorgänge.
Anweisung Ist überall zulässig, wenn: texld - ps_2_0 und höher, texldb - ps und texldp - ps Für die Texturkoordinate wird eine schreibgeschützte Menge verwendet (kann pro Pixel variieren, z. B. interpolierte Texturkoordinaten). dsx – ps und dsy – ps Für den Eingabeopernden wird eine schreibgeschützte Menge verwendet (kann pro Pixel variieren, z. B. interpolierte Texturkoordinaten). texldl - ps Der Benutzer stellt Detailebene als Argument bereit, sodass es keine Farbverläufe und somit kein Problem mit der Flusssteuerung gibt. texldd – ps Der Benutzer stellt Farbverläufe als Eingabeargumente bereit, sodass es kein Problem mit der Flusssteuerung gibt.
Diese Einschränkungen werden bei der Shaderüberprüfung streng erzwungen. Szenarien mit einer Branchbedingung, die aussieht, als würde sie konsistent über ein Primitive verzweigen, obwohl ein Operand im Bedingungsausdruck eine pixel-shader-berechnete Menge ist, fallen dennoch in Szenario A und sind nicht zulässig. Ähnlich verhält es sich bei Szenarien, in denen Gradienten für eine Shader-berechnete Menge x aus der dynamischen Flusssteuerung angefordert werden, in denen es jedoch scheint, dass x in keinem der Branches geändert wird, dennoch in Szenario A fallen und nicht zulässig sind.
Prädication ist in diesen Einschränkungen für die Flusssteuerung enthalten, sodass Implementierungen frei bleiben, die Implementierung von Branchanweisungen trivial mit prädikierten Anweisungen zu ersetzen.
Der Benutzer kann Anweisungen aus den Szenarien A und B zusammen verwenden. Angenommen, der Benutzer benötigt ein Beispiel für anisotrope Texturen, wenn eine Shader-Texturkoordinate berechnet wird. Die Texturlast wird jedoch nur für Pixel benötigt, die eine bestimmte Pro-Pixel-Bedingung erfüllen. Um diese Anforderungen zu erfüllen, kann der Benutzer die Texturkoordinate für alle Pixel berechnen, die sich außerhalb der pro Pixel variierenden Flusssteuerung und sofort mit den Anweisungen dsx - ps und dsy - ps berechnen. Dann kann der Benutzer innerhalb eines pro Pixel , wenn bool - ps/endif - ps block, texldd - ps (Texturlast mit vom Benutzer bereitgestellten Farbverläufen) verwenden, wobei die vorberechneten Farbverläufe übergeben werden. Eine andere Möglichkeit, dieses Verwendungsmuster zu beschreiben, besteht darin, dass zwar alle Pixel im Grundtyp die Texturkoordinaten berechnen und an der Farbverlaufsberechnung beteiligt sein mussten, dies jedoch nur die Pixel taten, die zum Samplen einer Textur benötigten.
Unabhängig von diesen Regeln liegt die Last weiterhin beim Benutzer, um sicherzustellen, dass das Register mit den Quelldaten für alle Ausführungspfade zuvor für alle Ausführungspfade initialisiert worden sein muss, bevor ein Farbverlauf berechnet wird (oder ein Texturbeispiel, das implizit einen Farbverlauf berechnet). Die Initialisierung temporärer Register wird im Allgemeinen nicht überprüft oder erzwungen.
Zugehörige Themen