流量控制限制

圖元著色器流程式控制制指令的限制會影響指令中可以包含多少層級的巢狀。 此外,使用漸層指示實作個別圖元流程式控制制有一些限制。

注意

當您使用 *_4_0_level_9_x HLSL 著色器設定檔時,您會隱含地使用 著色器模型 2.x 設定檔來支援 Direct3D 9 支援的硬體。 著色器模型 2.x 設定檔支援比 著色器模型 4.x 和更新版本的設定檔更有限的流程式控制制行為。

 

圖元著色器指令深度計數

ps_2_0不支援流量控制。 其他圖元著色器版本的限制如下所列。

ps_2_x的指令深度計數

每個指令都會根據一或多個巢狀深度限制計算。 下表列出每個指令從現有深度新增或減去的深度計數。

指令 靜態巢狀 動態巢狀 迴圈/rep 巢狀 呼叫巢狀
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 (bool - ps) -1 (如果 pred - psif_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

 

巢狀深度

巢狀深度定義可以從彼此內部呼叫的指令數目。 每種指令類型都有一或多個巢狀限制,如下表所示。

指令類型 最大值
靜態巢狀 如果 (D3DCAPS9,則為 24。D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0) ;否則為 0
動態巢狀 0 到 24,請參閱 D3DCAPS9。D3DPSHADERCAPS2_0.DynamicFlowControlDepth
rep 巢狀 0 到 4,請參閱 D3DCAPS9。D3DPSHADERCAPS2_0.StaticFlowControlDepth
呼叫巢狀 0 到 4,請參閱 D3DCAPS9。D3DPSHADERCAPS2_0.StaticFlowControlDepth (與 rep 限制無關)

 

ps_2_sw的指令深度計數

每個指令都會計算一或多個巢狀深度限制。 下表顯示每個指令從現有深度新增或減去的深度計數。

指令 靜態巢狀 動態巢狀 迴圈/rep 巢狀 呼叫巢狀
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 (bool - ps) -1 (如果 pred - psif_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
迴圈 - ps n/a n/a n/a n/a
endloop - ps n/a n/a n/a n/a
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

 

巢狀深度

巢狀深度定義可以從彼此內部呼叫的指令數目。 每種指令類型都有一或多個巢狀限制,如下表所示。

指令類型 最大值
靜態巢狀 24
動態巢狀 24
rep 巢狀 4
呼叫巢狀 4

 

ps_3_0的指令深度計數

每個指令都會根據一或多個巢狀深度限制計算。 下表顯示每個指令新增或減去現有深度的深度計數。

指令 靜態巢狀 動態巢狀 迴圈/rep 巢狀 呼叫巢狀
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 (bool - ps) -1 (如果 pred - psif_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

 

巢狀深度

巢狀深度定義可從彼此內部呼叫的指令數目。 每種指令類型都有一或多個巢狀限制,如下表所示。

指令類型 最大值
靜態巢狀 24
動態巢狀 24
迴圈/rep 巢狀 4
呼叫巢狀 4

 

ps_3_sw的指令深度計數

每個指令都會計算一或多個巢狀深度限制。 下表顯示每個指令從現有深度新增或減去的深度計數。

指令 靜態巢狀 動態巢狀 迴圈/rep 巢狀 呼叫巢狀
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 (bool - ps) -1 (如果 pred - psif_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
迴圈 - 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

 

巢狀深度

巢狀深度定義可從彼此內部呼叫的指令數目。 每種指令類型都有一或多個巢狀限制,如下表所示。

指令類型 最大值
靜態巢狀 24
動態巢狀 24
迴圈/rep 巢狀 4
呼叫巢狀 4

 

與螢幕漸層Per-Pixel流程式控制件的互動

圖元著色器指令集包含數個指示,這些指令會產生或使用螢幕空間 x 和 y 的數量漸層。 漸層最常見的用法是計算紋理取樣的詳細資料層級計算,如果是等向性篩選,請沿著等向性軸選取樣本。 一般而言,硬體實作會在多個圖元上同時執行圖元著色器, (例如 2x2 格線) ,因此著色器中計算的數量漸層可以合理地近似為相鄰圖元中相同執行點的值差異。

當流量控制存在於著色器中時,當相鄰圖元可能會執行個別的流程式控制制路徑時,指定分支路徑內要求的漸層計算結果模棱兩可。 因此,使用任何圖元著色器作業,會要求在流程式控制制建構內的位置發生漸層計算,而該作業可能會因所要點陣化之特定基本類型而有所不同,

所有圖元著色器指令都會分割成允許的作業,以及流量控制內不允許的作業:

  • 案例 A:在流程式控制制內不允許的作業,這些作業可能會因基本型別中的圖元而有所不同。 其中包括下表所列的作業。

    指令 當流程式控制制中允許:
    texld - ps_2_0和 uptexldb - pstexldp - ps 暫存暫存器用於紋理座標。
    dsx - psdsy - ps 暫存暫存器用於運算元。

     

  • 案例 B:任何位置允許的作業。 其中包括下表所列的作業。

    指令 允許在:
    texld - ps_2_0和 uptexldb - pstexldp - ps 唯讀數量用於紋理座標 (可能會因圖元而異,例如插補紋理座標) 。
    dsx - psdsy - ps 唯讀數量用於輸入運算元 (可能會依圖元而有所不同,例如插補紋理座標) 。
    texldl - ps 使用者提供詳細資料層級做為引數,因此沒有任何漸層,因此流程式控制制沒有問題。
    texldd - ps 使用者提供漸層做為輸入引數,因此流程式控制制沒有任何問題。

     

這些限制會在著色器驗證中嚴格強制執行。 具有分支條件的案例看起來會一致地跨基本類型分支,即使條件運算式中的運算元是圖元著色器計算的數量,但仍會落在案例 A 中,但不允許這麼做。 同樣地,某些著色器計算數量 x 上要求漸層的案例,從動態流程式控制制內,但其中 x 似乎未在任何分支上修改,但仍不允許進入案例 A 且不允許。

流程式控制制上的這些限制中包含預先分割,因此實作可以隨意交換分支指令的實作與述詞指示。

使用者可以同時使用 A 和 B 案例中的指示。 例如,假設使用者需要具有著色器計算紋理座標的等向性紋理範例;不過,只有滿足某些個別圖元條件的圖元才需要紋理載入。 為了符合這些需求,使用者可以計算每個圖元不同流程式控制制以外的所有圖元紋理座標,並使用 dsx - psdsy - ps 指示立即計算漸層。 然後,如果 bool - psendif - ps / 區塊在每圖元內,使用者可以使用texldd - ps (紋理載入與使用者提供的漸層) ,傳遞預先計算的漸層。 另一種描述此使用模式的方式是,雖然基本型別中的所有圖元都必須計算紋理座標並涉及漸層計算,但只有取樣紋理所需的圖元實際執行此動作。

不論這些規則為何,使用者仍會承擔負擔,以確保在計算任何漸層 (或執行隱含計算漸層) 的紋理範例之前,包含來源資料的暫存器必須先針對所有執行路徑預先初始化。 暫存暫存器初始化一般不會經過驗證或強制執行。

圖元著色器指示