Share via


語法變數

使用下列語法規則來宣告 HLSL 變數。

[Storage_Class][Type_Modifier] 類型名稱[索引] [: Semantic] [: Packoffset] [: Register];[注釋][= Initial_Value]

參數

Storage_Class

選擇性的儲存體類別修飾詞,可提供有關變數範圍和存留期的編譯器提示;修飾詞可以依任何順序指定。

描述
extern 將全域變數標示為著色器的外部輸入;這是所有全域變數的預設標記。 無法與 靜態結合。
nointerpolation 請勿在將頂點著色器的輸出傳遞至圖元著色器之前插入。
精確 套用至變數時的 精確 關鍵字會限制用來產生指派給該變數之值的任何計算方式如下:
  • 個別的作業會分開。 例如,當多子和新增作業可能已合併到一個不想要的作業時, 精確 會強制作業保持分開。 相反地,您必須明確使用不想要的內建函式。
  • 維護作業順序。 當指令順序可能已隨機排列以提升效能時, 精確 可確保編譯器會保留寫入的順序。
  • IEEE 不安全的作業受到限制。 如果編譯器可能已使用不考慮 NaN 的快速數學運算, (不是數位) ,而 INF (無限) 值, 則精確 強制遵守 NaN 和 IN光圈值的 IEEE 需求。 如果沒有 精確,這些優化和數學運算並不安全。
  • 限定變數 精確 不會讓使用變數 精確的作業。 由於精確只會傳播至對指派給精確限定變數之值的作業,因此正確讓所需的計算精確可能很棘手,因此建議您直接在宣告著色器輸出的位置標記著色器輸出,無論是在結構欄位上或輸出參數上,還是輸入函式的傳回型別。 藉由停用可能會影響最終結果的優化,藉由停用因累積有效位數差異差異而影響最終結果的優化,以這種方式控制優化的能力會維持修改輸出變數的結果不一致。 如果您想要著色器進行鑲嵌,以維護水緊密修補接點,或比對多個階段的深度值時,它很有用。 範例程式碼
    HLSLmatrix g_mWorldViewProjection;
    float3 InPos 中的 void main (: Position, out precise float4 OutPos : SV_Position)
    {
    作業精確,因為它會參與精確的參數 OutPos
    OutPos = mul ( float4 ( InPos, 1.0 ) , g_mWorldViewProjection ) ;
    }
共用 標記變數以在效果之間共用;這是編譯器的提示。
groupshared 為計算著色器標示執行緒群組共用記憶體的變數。 在 D3D10 中,具有群組共用儲存類別的所有變數大小上限為 16 kb,在 D3D11 中,大小上限為 32 kb。 請參閱範例。
static 標記區域變數,使其一次初始化,並在函式呼叫之間保存。 如果宣告不包含初始化運算式,此值會設定為零。 應用程式看不到標示 為靜態 的全域變數。
均勻 標記變數,其資料在整個著色器執行期間為常數 (,例如頂點著色器中的材質色彩) ;全域變數預設會被視為 統一
volatile 標記經常變更的變數;這是編譯器的提示。 此儲存類別修飾詞僅適用于區域變數。
注意: HLSL 編譯器目前會忽略此儲存體類別修飾詞。

Type_Modifier

選擇性變數類型修飾詞。

描述
const 標記著色器無法變更的變數,因此必須在變數宣告中初始化它。 全域變數預設會被視為 const , (藉由將 /Gec 旗標提供給編譯器) 來隱藏此行為。
row_major 標記變數,將四個元件儲存在單一資料列中,以便儲存在單一常數暫存器中。
column_major 標記變數,將 4 個元件儲存在單一資料行中,以優化矩陣數學。

注意

如果您未指定類型修飾詞值,編譯器會使用 column_major 做為預設值。

類型

任何列在 資料類型中的 HLSL 類型, (DirectX HLSL)

Name[Index]

可唯一識別著色器變數的 ASCII 字串。 若要定義選擇性陣列,請使用陣列大小的 索引 ,這是正整數 = 1。

語義

編譯器用來連結著色器輸入和輸出的選擇性參數使用資訊。 頂點和圖元著色器有數個預先定義的 語意 。 除非編譯器是在全域變數上宣告,或是傳遞至著色器的參數,否則編譯器會忽略語意。

Packoffset

手動封裝著色器常數的選擇性關鍵字。 請參閱 packoffset (DirectX HLSL)

註冊

手動將著色器變數指派給特定暫存器的選擇性關鍵字。 請參閱 註冊 (DirectX HLSL)

注釋 (s)

附加至全域變數之字串形式的選擇性中繼資料。 效果架構會使用注釋,並由 HLSL 忽略;若要查看更詳細的語法,請參閱 注釋語法

Initial_Value

選擇性的初始值 (s) ;值數目應該符合 Type中的元件數目。 每個標示 extern 的全域變數都必須以常值初始化;標示 為靜態 的每個變數都必須以常數初始化。

未標示 為靜態extern 的全域變數不會編譯為著色器。 編譯器不會自動設定全域變數的預設值,也無法在優化中使用它們。 若要初始化這種類型的全域變數,請使用反映來取得其值,然後將值複製到常數緩衝區。 例如,您可以使用ID3D11ShaderReflection::GetVariableByName方法來取得變數、使用ID3D11ShaderReflectionVariable::GetDesc方法來取得著色器變數描述,並從D3D11_SHADER_VARIABLE_DESC結構的DefaultValue成員取得初始值。 若要將值複製到常數緩衝區,您必須確定緩衝區是以 CPU 寫入存取權建立, (D3D11_CPU_ACCESS_WRITE) 。 如需如何建立常數緩衝區的詳細資訊,請參閱 如何:建立常數緩衝區

您也可以使用 效果架構 自動處理反映和設定初始值。 例如,您可以使用 ID3DX11EffectPass::Apply 方法。

範例

以下是著色器變數宣告的數個範例。

float fVar;
float4 color;
float fVar = 3.1f;

int iVar[3];

int iVar[3] = {1,2,3};

uniform float4 position : SV_POSITION; 
const float4 lightDirection = {0,0,1};
      

群組共用

HLSL 可讓計算著色器的執行緒透過共用記憶體交換值。 HLSL 提供屏障基本類型,例如 GroupMemoryBarrierWithGroupSync等等,以確保讀取和寫入到著色器中共用記憶體的正確順序,以及避免資料競爭。

注意

硬體會在群組中執行執行緒 (變形或波浪前端) ,而當只有同步處理屬於相同群組的執行緒正確時,可能會省略屏障同步處理來提升效能。 但基於下列原因,我們強烈建議我們不要省略此專案:

  • 這項省略會導致無法移植的程式碼,在某些硬體上可能無法運作,而且不適用於通常執行較小群組中線程的軟體點陣化程式。
  • 相較于使用所有線程屏障,您可能透過這項省略而達到的效能改善將會是次要的。

在 Direct3D 10 中,寫入 群組共用時不會同步處理執行緒,因此這表示每個執行緒僅限於陣列中用於寫入的單一位置。 寫入時,請使用 SV_GroupIndex 系統值來編制此陣列的索引,以確保沒有任何兩個執行緒可以衝突。 就讀取而言,所有線程都可以存取整個陣列以供讀取。

struct GSData
{
    float4 Color;
    float Factor;
}

groupshared GSData data[5*5*1];

[numthreads(5,5,1)]
void main( uint index : SV_GroupIndex )
{
    data[index].Color = (float4)0;
    data[index].Factor = 2.0f;
    GroupMemoryBarrierWithGroupSync();
    ...
}

打包

封裝向量和純量子元件,其大小足以防止跨越暫存器界限。 例如,這些全都是有效的:

cbuffer MyBuffer
{
    float4 Element1 : packoffset(c0);
    float1 Element2 : packoffset(c1);
    float1 Element3 : packoffset(c1.y);
}
        

無法混合封裝類型。

如同 register 關鍵字,packoffset 可以是特定目標。 子元件封裝僅適用于 packoffset 關鍵字,而非 register 關鍵字。 在 cbuffer 宣告內,Direct3D 10 目標會忽略 register 關鍵字,因為它假設為跨平臺相容性。

已封裝的專案可能會重迭,而且編譯器不會發生錯誤或警告。 在此範例中,Element2 和 Element3 會與 Element1.x 和 Element1.y 重迭。

cbuffer MyBuffer
{
    float4 Element1 : packoffset(c0);
    float1 Element2 : packoffset(c0);
    float1 Element3 : packoffset(c0.y);
}
        

使用 packoffset 的範例為: HLSLWithoutFX10 範例

(DirectX HLSL) 變數